jquery 两个写法是不是一样的

第一种

    $('.navClass').each(function() {
        $(this).find('.navItemClass').on('click', function (e) {
            ...
        });
    });

第二种

    $('.navClass').on('click', '.navItemClass', function (e) {
        ...
    });

第一种和第二种有区别没?

第一种那样的怎么事件委派?

阅读 1.4k
2 个回答

简单的说,不一样!

第一种情况下是对对已经存在的 DOM,去逐一绑定事件。如果绑定事件之后容器内的元素发生变化(尤其是增加),新元素是不会有事件的,除非再绑。

第二种情况是直接在容器上绑定事件,代理内部元素的对应事件,因此,容器内的元素是可以动态变化的(因为事件是绑在容器上),新增加的元素也会有相应的事情(毕竟是容器代理)。

不过第二种也有坑,如果内部元素上绑定了事件,而且在事件处理中阻止冒泡,那容器对该元素的代理就失效了,因为事件没冒上来嘛,容器压根不知道有事发生。

其实第一种,你还可以写作

$('.navClass .navItemClass').on('click', function (){
  //TODO
})

它们有什么区别呢?从做的事情上来说,他们都是给 .navItemClass 绑定了一个点击事件,但是如果在一些情况下,第一种可能就不能正常工作了,因为相对于第一种而言,第二种利用了事件的另一个特性 冒泡,这种定义事件绑定的方式也叫 事件委托

现在,你在页面上使用第一种方式绑定了事件,如果你使用 ajax 加载的数据需要拼接成一个 .navItemClass 的 HTML 代码使用 append 或者其他方式放到 .navClass 下,这时候,你会发现,在点击时之前绑定的 click 事件并没有被响应。而如果你使用第二种方式,就没有问题。

这是因为,第一种的方式他是对于已有 DOM 的一种绑定方式,当如果在绑定这个事件时,对应的 DOM 如果不存在,那么 jQuery 也不会报错,但是这个事件并没有被有效绑定。

举一个典型的例子,我们都知道,我们通常应该把 script 标签放在页面的最后去引入它,因为浏览器的渲染时从上往下的,DOM 绑定事件的代码,或者操作 DOM 都应该在 DOM 加载完成后在执行,否则就会出现 DOM 尚未渲染,而事件已经绑定的情况(无效)。当然,这也可以放在 load 事件或者 DOMContentLoaded 事件中绑定。

第二种方式则不一样,它事件的绑定对象是 .navClass,它利用了事件回冒泡的特性,当 .navClass 的后代被 click 时,如果没有被处理,事件冒泡到 .navClass 时,他会根据事件发起的后代元素根上 on 方法的第二个元素做匹配,进而响应处理事件。

简单的说:第一种方式就是给元素本身绑定了事件,如果要想响应这个事件,那这个元素一定要在绑定时存在。
而第二种则是,把事件绑定到了被监听元素的上级元素,由他的上级元素来进行处理,被关注的元素不一定要在绑定时存在。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题