2015-07-02 164 views
0

我知道我可以在复选框上添加一个clickchange侦听器。当复选框未选中时,处理程序将按钮的disabledprop更改为true。这很容易。任何方式来创建“状态”侦听器而不是“事件”侦听器?

但是,这不是事件驱动的,有没有办法让这是“状态”驱动?

如果取消选中复选框的“状态”,则该按钮的“状态”将始终处于禁用状态。什么样的事件触发状态改变并不重要。如果复选框处于一种状态,则该按钮始终处于相应的状态。而已。

下面是标准事件驱动代码的示例,其中只要未选中条款和条件复选框,就应禁用结帐按钮。

$('input[name="terms-and-conditons"]').change(function(e, tmpl){ 
    if(e.target.checked === true){ 
     $('#checkout-button').prop("disabled", false); 
    } else { 
     $('#checkout-button').prop("disabled", true); 
    }; 
    }); 

不幸的是,这并没有考虑到初始状态,因为它需要事件发生才能发生。在页面加载,如果该复选框被选中时,按钮仍然可以启用,除非小心地记得按钮的初始状态设置为禁用:

// setting the initial state 
    $('#checkout-button').prop("disabled", true); 
    $('input[name="terms-and-conditons"]').prop("checked", false); 

    $('input[name="terms-and-conditons"]').change(function(e, tmpl){ 
    if(e.target.checked === true){ 
     $('#checkout-button').prop("disabled", false); 
    } else { 
     $('#checkout-button').prop("disabled", true); 
    }; 
    }); 

我不知道是否有一种方法创造一个“国家听众”。无论发生什么事件(即使没有事件,如页面加载的默认值),按钮状态将始终与复选框状态保持一致。它可以通过单击,空格按键,更改事件,只需在Chrome控制台中直接编辑HTML的人员进行更改,或者它可能刚刚以某种状态加载。关键是,只是的东西是。而某些事物的状态会随着其他事物的状态而自动改变。

+1

有没有这样的功能,你要求内置到浏览器。您必须通过观察所有可能的事件来指明相关状态的变化,从而通过自己的JS实现它。 – jfriend00

+0

这就是我一直在做的事情。所以解决方案实际上只是为单个ID或类复选框注册一大堆事件侦听器和处理程序,并希望您没有忘记解释某个事件? – fuzzybabybunny

+1

在现代浏览器中,特定属性上的[MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)可能是更通用的更改侦听器吗? – jfriend00

回答

2

您可以使用trigger强制事件处理程序在页面加载时运行。您也可以使用复选框状态更改按钮状态。

// setting the initial state 
$('#checkout-button').prop("disabled", true); 

$('input[name="terms-and-conditons"]').on('change', function() { 
    $('#checkout-button').prop("disabled", !$(this).is(':checked')); 
}).trigger('change'); 
// ^^^^^^^^^^^^^^^^^ 
+0

在这种情况下,我不想使用事件处理程序。事件是特定的。即使某事物的状态正在改变,'change'事件也不会与'keyup'事件同时触发。用一个现实世界的比喻:“当一辆汽车碰到一棵树时,它会受到损坏,保险就会把钱付出。”这是事件驱动的。我想要一些类似“汽车损坏,保险支付”。 – fuzzybabybunny

+0

@fuzzybabybunny正如jfriend上面所说,“没有像你在浏览器中要求的那样的功能。你必须通过观察所有可能的事件来实现它与你自己的JS通过观察所有可能的事件,指出相关状态的变化你必须使用事件驱动的编程 – Tushar

0

嗨,你想这样的事情? http://jsfiddle.net/elviz/gg5r92q0/1/

$(document).ready(function(){ 

    var is_click = $("#myCheckbox").is(':checked'); 

    if(is_click == false){ 
    $("#checkout-button").prop('disabled', true); 
    }else{ 
    $("#checkout-button").prop('disabled', false); 
    } 

    $("#myCheckbox").click(function(){ 

    var is_click = $("#myCheckbox").is(':checked') 

     if(is_click == false){ 
       $("#checkout-button").prop('disabled', true); 
     }else{ 
      $("#checkout-button").prop('disabled', false); 
     } 

}); 


}); 
+0

按钮的状态取决于你的复选框的状态 – knives22

2

你想要什么样

我认为你需要参考

发布/订阅模式或观察者模式嗨伙计我的事情

http://addyosmani.com/resources/essentialjsdesignpatterns/book/

this可以帮助你,你想

和一件事是什么,我想补充一点,只有chorme浏览器支持.Observe()查看详细研究方法,你可以参考

http://www.html5rocks.com/en/tutorials/es7/observe/

+0

谢谢。我一直在使用MeteorJS,所以我对这个pub/sub和observer模式非常熟悉。到目前为止,它真的非常接近我所期待的。实际上,当我处理JS代码时,我可以使用状态驱动的风格进行编码,但只要我触摸DOM,我必须恢复到事件驱动的风格,如果这有意义的话。 – fuzzybabybunny

0

您可以绑定到一个元素属性的对象包装器,或者将这些元素集中绑定到您自己的对象上。我发现最容易拥有一对地图,注册人作为关键对象或用户等,以及属性名称,然后地图保留当前值,并且(当我到达它时)生成器或迭代器将更新相应注册者的属性。下面是一个没有扩展nodeList原型和数组函数的例子,我做了扩展,因为循环可以很好,你会看到代码。

这是我在codepen中的一些代码,我在9月15日开始的一个项目中。我试图获得一个接口,用于构建和记录阅读测试段落和问题以维护状态,能够重新创建状态并提供关于学习的一些有用的线索......

代码是多余的,因为在没有观察者Addi提到的情况下,我从来没有做过这个工作。在Polymer组件中,您不必自己进行绑定。你也可以尝试新的spec v1聚合物两种方法。它基本上有一个清晰的对象观察,还有很多其他很酷的功能,我只是遇到了一些规范问题,对合同要求进行了一些更改。

`
var archive = []; this.archive = []; // TODO ME:记录工作,记录报告,返回重新impl状态,但需要一些'光滑的'来保持可更新和快速...所以仔细检查,然后再做至少一只手满与发生器/代理/地图时间...。尝试开启和关闭线程

 var inputNodes=document.querySelectorAll("input");//NOTE TODO ME: replace with symbol iterator of symbols for dom nodes HTML REPLACED IN DEMO 6; 
     var counterOne=inputNodes.length; 
     this.inputArray=[];//check 
     this.propertyArray=[];//check add? 
     for(var i=0; i<counterOne;i++) 
     { 
       var newProp=inputNodes[i].attributes.id.value; 
       var elem=document.getElementById(newProp); 
       this.propertyArray.push(newProp); 
       this.inputArray.push(elem); 
     } 
var selectNodes=document.querySelectorAll("select"); 
var counterT=selectNodes.length; 
for(var zz=0; zz<counterT;zz++){ 
    var newProp3=selectNodes[zz].attributes.id.value; 
    var za=document.getElementById(newProp3); 
    this.propertyArray.push(newProp3); 
    this.inputArray.push(za); 
} 
var taNodes=document.querySelectorAll("textarea"); 
var counterTwo=taNodes.length; 
for(var i=0; i<counterTwo;i++){ 
    var newProp2=taNodes[i].attributes.id.value; 
    var ta=document.getElementById(newProp2); 
    this.propertyArray.push(newProp2); 
    this.inputArray.push(ta); 
} 
    NOTE: TODO-AGAIN: ME--reinstitute the extensions to nodeListProto or at least make a helper func, this looks gross 
    this.propertyArray.forEach((prop, index)=>{ 
       var elem=this.inputArray[index]; 
       if(elem.nodeName==="TEXTAREA"){ 
        elem.value=elem.innerHTML; 
       } 
       if(elem.nodeName==="SELECT"){ 
        console.log(elem.selectedIndex, "LOOK HERE DUMMY"); 
        elem.value=elem.children[elem.selectedIndex].value; 

       } 
      var val=elem.value; 
     Object.defineProperty(this, prop,{ 
          enumerable: true, 
          configurable: true, 
           get: function() { 
            if(elem.type=="checkbox" || elem.type=="radio"){ 
         this.archive.push({name:prop, value: elem.checked}); 

             return elem.checked; 
            } 
            else if(elem.nodeName==="SELECT"){ 

             var retVal=(elem.selectedIndex==undefined)?elem.children[1].value:elem.children[elem.selectedIndex].value; 
             return retVal; 
            } 

            else{ 
             if(elem.nodeName==="TEXTAREA"){ 
              var val=elem.value; 
           } 
       this.archive.push({name:prop, value: val}); 
            return val;   
            } 
            }, 
          set: function() { 
            if(elem.type=="checkbox" || elem.type=="radio"){prop=elem.checked;                  } 
            else{ 

          prop = val; 
            } 
           } 

        }); 
       if(elem.nodeName=="SELECT"){ 
        var nom=elem.attributes.id.value; 
        elem.addEventListener("blur",()=>{ this[`${nom}Func`]; alert("the thing changed");},false);} 
       if(elem.type!="button"){ 
         elem.addEventListener("change",()=>{ 
         var keys=Object.keys(this); 
        console.log(keys); 
        keys.forEach((key)=>{ 
        console.log(key, this[key]); 
        }); 

       console.log(this[prop], elem.value,elem.checked, prop, "newprop values here", this.archive) 
         }, false); 
          }  }, this); 
     this.codeMirror={};//check 
`