为什么我不能设置群发事件处理程序?

时间:2014-03-28 19:41:49

标签: javascript jquery

所以这两个工作正常:

$(document).on("click", "#_something", function(){
    $('#vid').attr('src',video_config["something"].video);

});
$(document).on("click", "#_anotherthing", function(){
    $('#vid').attr('src',video_config["anotherthing"].video);

});

但是,somethingnothing是我制作的对象的属性,所以我尝试这样做:

for (var key in video_list){
    $(document).on("click", "#_"+key, function(){
        $('#vid').attr('src',video_list[key].video);
    });
}

哪种搞砸了,并将所有src值设置为我的最后video_list[key].video值。换句话说,这为所有src属性分配了相同的值。

如果不手动编写每个事件处理程序,如何正确执行此操作?

3 个答案:

答案 0 :(得分:4)

这是因为您的Handler函数捕获了作为父函数作用域的key变量。处理程序执行时,key具有最后一个值。

修复是通过使用另一个函数范围捕获每次迭代的当前值。像这样:

for (var k in video_list) {
  function(key) {
    // create your event handler here using key
  }(k);
}

这个问题在这个问题中解释了与此问题基本相同: javascript closure in a for loop

在ES6浏览器中,let是块作用域,您可以将其用作快捷方式:

for (let k in video_list) {
  let key = k;
  // same code as your question goes here, using key.
}

答案 1 :(得分:2)

这是使用一个事件处理程序,类和数据属性的简单方法:

$(document).on("click", ".video", function(){
    var key = $(this).data("key"); // in the element add data-key="xyz"
    $('#vid').attr('src',video_list[key].video);
});

答案 2 :(得分:1)

快速而肮脏的黑客行为:

for (var key in video_list){
    (function(key){// create a new context, so not all handlers point the the same key
        $(document).on("click", "#_"+key, function(){
            $('#vidSrc').attr('src',video_list[key].video);
        });
    })(key);
}

正确的方法:

$(document).on("click", ".some-new-class-you-just-defined", function() {
    $(this).attr('src', video_list[$(this).attr('id').slice(1)].video);
});

编辑:将子字符串添加到id。最好有一些查找机制,而不是像@jods建议的那样将它存储在id中。