有没有办法创建“状态”监听器而不是“事件”监听器?

时间:2015-07-02 05:40:38

标签: javascript jquery

我知道我可以在复选框上添加clickchange侦听器。取消选中该复选框后,处理程序会将按钮的disabled prop更改为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);
    };
  });

我想知道是否有办法创建“州听众”。无论发生什么事件(即使没有事件,如pageload上的默认值),按钮状态也将始终与复选框状态保持同步。它可以通过点击,空格键按下,更改事件,直接在Chrome控制台中编辑HTML的人进行更改,也可以最初加载某种状态。关键是只是。某些事物的状态可以随着其他事物的状态自动改变。

4 个答案:

答案 0 :(得分: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');
// ^^^^^^^^^^^^^^^^^

答案 1 :(得分:2)

亲爱的,我想要的就是你想要的东西

我认为你需要参考

发布/订阅模式或观察者模式

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

这可能会帮助你达到你想要的目标

并且有一件事我想补充一点只有chorme浏览器支持.Observe()方法进行详细研究,你可以参考

<强> http://www.html5rocks.com/en/tutorials/es7/observe/

答案 2 :(得分: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);
        }

 }); 


 });

答案 3 :(得分:0)

您可以绑定到元素属性上的对象包装器,或者将元素一起绑定到您自己的do-something对象。我发现最简单的方法是将一对地图,注册人作为密钥对象或用户等,以及属性名称,然后地图保留当前值(当我到达时),生成器或迭代器将更新相应注册人的属性。下面是一个没有使用数组函数扩展nodeList原型的例子,我做了扩展,因为循环可以很好,你会看到代码。

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

代码在整个过程中是多余的,因为如果没有上面提到的Observers 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
`