2015-10-06 67 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

当我测试它时,单击标签会显示上述代码的提示。更改输入框也会产生警告,注意:我必须关闭输入框(单击框,输入一些文本,单击框)。 –