首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在循环中创建的jQuery事件处理程序

在循环中创建的jQuery事件处理程序
EN

Stack Overflow用户
提问于 2011-10-15 07:33:09
回答 5查看 11.5K关注 0票数 20

所以我有一组这样的事件:

代码语言:javascript
复制
$('#slider-1').click(function(event){   
        switchBanners(1, true);
});
$('#slider-2').click(function(event){   
        switchBanners(2, true);
});
$('#slider-3').click(function(event){   
        switchBanners(3, true);
});
$('#slider-4').click(function(event){   
        switchBanners(4, true);
});
$('#slider-5').click(function(event){   
        switchBanners(5, true);
});

我想通过一个循环来运行它们,我已经运行了类似这样的东西:

代码语言:javascript
复制
for(i = 1; i <= totalBanners; i++){
    $('#slider-' + i).click(function(event){    
            switchBanners(i, true);
    });
}   

从理论上讲,这应该是可行的,但一旦我加载了文档,它似乎就不起作用了……它不会像单击时那样对任何特定的div id做出响应...无论我单击哪个div,它都会遍历每个div。我想动态创建更多的事件监听器,但我首先需要这些……

我遗漏了什么?

EN

回答 5

Stack Overflow用户

发布于 2011-10-15 07:37:01

这是人们经常遇到的问题。

JavaScript没有块作用域,只有函数作用域。因此,您在循环中创建的每个函数都是在相同的变量环境中创建的,因此它们都引用相同的i变量。

要在新的变量环境中限定变量的范围,您需要调用一个函数,该函数具有引用您想要保留的值的变量(或函数参数)。

在下面的代码中,我们使用函数参数j引用它。

代码语言:javascript
复制
   // Invoke generate_handler() during the loop. It will return a function that
   //                                          has access to its vars/params. 
function generate_handler( j ) {
    return function(event) { 
        switchBanners(j, true);
    };
}
for(var i = 1; i <= totalBanners; i++){
   $('#slider-' + i).click( generate_handler( i ) );
}

在这里,我们调用了generate_handler()函数,传入了i,并让generate_handler()返回一个引用本地变量的函数(在函数中名为j,不过您也可以将其命名为i )。

只要函数存在,返回函数的变量环境就会一直存在,因此它将继续引用创建它时/所在环境中存在的任何变量。

更新:i之前添加了var,以确保其声明正确。

票数 41
EN

Stack Overflow用户

发布于 2011-10-15 07:49:02

与其做这样的事..。嗯..。不计后果,你应该附加一个单一的事件监听器,并捕捉我们他们冒泡的事件。它被称为“事件委派”。

一些链接:

  • http://davidwalsh.name/event-delegate
  • http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-javascript-event-delegation-in-4-minutes/
  • http://www.sitepoint.com/javascript-event-delegation-is-easier-than-you-think/
  • http://lab.distilldesign.com/event-delegation/

研究一下这个。学习javascript中的事件管理是一件非常重要的事情。

票数 7
EN

Stack Overflow用户

发布于 2011-10-15 09:03:15

编辑:看到这个答案获得了赞成票,并认识到它使用的是旧语法。下面是一些更新的语法,使用jQuery的"on“事件绑定方法。同样的原则也适用。您绑定到最近的未销毁的父级,侦听指定选择器上的单击。

代码语言:javascript
复制
$(function() {
  $('.someAncestor').on('click', '.slider', function(e) {
    // code to do stuff on clicking the slider. 'e' passed in is the event
  });
});

注意:如果您的初始化链已经有一个合适的位置来插入侦听器(即。您已经有了document ready或onload函数),不需要将其包装在此示例的$(function(){})方法中。您只需将$('.someAncestor')...部件放在适当的位置。

保留原始答案以获得更全面的解释和遗留示例代码:

我同意tereško的观点:委托事件比按需点击更强大。访问整个滑块元素组的最简单方法是为每个滑块元素提供一个共享类。假设是"slider“,那么你可以将一个通用事件委托给所有的".slider”元素:

代码语言:javascript
复制
$(function() {
    $('body').delegate('.slider', 'click', function() {
        var sliderSplit = this.id.split('-'); // split the string at the hyphen
        switchBanners(parseInt(sliderSplit[1]), true); // after the split, the number is found in index 1
    });
});

利德尔小提琴:http://jsfiddle.net/2KrEk/

我委托"body“只是因为我不知道你的HTML结构。理想情况下,您将委托给您知道不会被其他DOM操作破坏的所有滑块中最接近的父对象。通常是某种包装器或容器div。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7774636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档