2015-07-02 234 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 
`