2015-10-06 64 views
0

我嘗試編寫一個小的jQuery腳本並遇到問題。我有一個包含html和一些事件的對象數組,這些事件在HTML被加載到DOM中時應該被觸發。用數組動態註冊事件

出於測試目的,我對象數組減少到一個物體:

<!doctype html> 
<html> 
    <head><title>Test</title></head> 
    <body> 
     <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> 
     <div id="wrapper"></div> 
     <script> 
      var element = { 
       id  : 'xyz', 
       html : '<div id="xyz"><label>ABC</label><input type="text"></div>', 
       events : [ 
          { 
           'selector':'label', 
           'event_name':'click', 
           'callback':function(event, element){ 
            alert('[EVENT] Click <label>'); 
            console.log(event); 
            console.log(element); 
           } 
          }, 
          { 
           'selector':'input', 
           'event_name':'change', 
           'callback':function(event, element){ 
            alert('[EVENT] Change <input>'); 
            console.log(event); 
            console.log(element); 
           } 
          } 
        ] 
      } 

      $(document).ready(function(){ 
       $(element.html).appendTo('#wrapper'); 
       for(var i = 0; i < element.events.length; i++){ 
        //var eventReg = $.extend({},element.events[i]); //Its not a object-clone-problem 
        var eventReg = element.events[i]; 
        console.log(eventReg.event_name); 
        console.log(eventReg.selector); 
        console.log('#####################'); 
        $('#'+ element.id).on(eventReg.event_name, eventReg.selector, function(event){eventReg.callback(event, this)}); 
       } 
      }); 
     </script> 
    </body> 
</html> 

element -object具有ID「xyz」(其也是div的ID,這將是插入)。一旦文檔準備就緒,我將HTML(element.html)添加到div#wrapper。現在我瀏覽了element.events中的所有對象。這些對象包含一個選擇器,一個事件名稱和一個回調函數。由於該事件也是動態的,因此我想使用$.on()方法註冊事件。我綁定了div#xyz上的事件,該事件現在位於DOM中幷包含元素。好吧,我想你明白了,我試了一下。

現在:我的問題是,當我跑我期望得到不同alert()當我點擊<label>和不同alert()當我改變了<input>值的腳本。但在這兩個事件中,相同的回調函數(我陣列中的最後一個)被註冊...

因此,請點擊<label>調用<input>-change事件的callback()。有誰能給我一個提示,我錯過了什麼?非常感謝。

編輯 解決方案

娟注意到,這個問題實際上是重複的。那麼從技術角度來說,我在應用該解決方案時遇到了問題。幸運的是,胡安在評論中已經給了我答案。我需要一點,但比我想通了,想在這裏補充它,因爲它可能會有所幫助別人:

$('#'+ element.id).on(eventReg.event_name, eventReg.selector, (function(cb){return function(event){cb(event, this)}})(eventReg.callback)); 
+1

這是因爲eventReg是由您的事件處理程序和點共享到由匿名函數被調用的時候是最後一個。看到我把它鏈接到的問題。請參閱下面的解決您的用例的最簡單方法,我稱之爲「凍結封閉」。它每次通過具有立即自我調用功能的循環創建額外的閉包。 –

+1

'(function(cb){return function(event){cb(event,this)})})(eventReg.callback);' –

+0

感謝一堆胡安!它花了我一點,但現在我得到它:)我使用這部分,而不是'function(event){eventReg.callback(event,this)}',因爲它返回該函數。 – websupporter

回答

0
<!doctype html> 
<html> 
    <head><title>Test</title></head> 
    <body> 
     <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> 
     <div id="wrapper"></div> 
     <script> 
      var element = { 
       id  : 'xyz', 
       html : '<div id="xyz"><label>ABC</label><input type="text"></div>', 
       events : [ 
          { 
           'selector':'label', 
           'event_name':'click', 
           'callback':function(event, element){ 
            alert('[EVENT] Click <label>'); 
            console.log(event); 
            console.log(element); 
           } 
          }, 
          { 
           'selector':'input', 
           'event_name':'change', 
           'callback':function(event, element){ 
            alert('[EVENT] Change <input>'); 
            console.log(event); 
            console.log(element); 
           } 
          } 
        ] 
      } 

      $(document).ready(function(){ 
       $(element.html).appendTo('#wrapper'); 
       for(var i = 0; i < element.events.length; i++){ 
        //var eventReg = $.extend({},element.events[i]); //Its not a object-clone-problem 
        var eventReg = element.events[i]; 
        console.log(eventReg.event_name); 
        console.log(eventReg.selector); 
        console.log('#####################'); 
        $('#'+ element.id).on(eventReg.event_name, eventReg.selector, function(event){eventReg.callback(event, this)}); 
       } 
      }); 
     </script> 
    </body> 
</html> 

試試這個吧。我相信你所缺少的是第37行「元素」應該是「元素」。嘗試下次檢查你的JS控制檯的錯誤,這彈出。

編輯: 這裏是工作代碼: https://jsfiddle.net/zwx4quuh/

+0

沒有抱歉。在我的代碼中錯別字,但不是問題。謝謝。 – websupporter

+0

更新了上面的代碼,仍然遇到問題。 – websupporter

+0

當我測試它時,單擊標籤會顯示上述代碼的提示。更改輸入框也會產生警告,注意:我必須關閉輸入框(單擊框,輸入一些文本,單擊框)。 –