jq事件绑定

$(document).on('click',function(event){
     if($(event.target).is('[data-btn-rank]')){
         alert("ppp")     
     }
})
$("body").on('click','[data-btn-rank]',function(event){
     alert("ppp")            
})

这两种绑定方法效果完全一样吗?还是有其他区别?

阅读 3.2k
5 个回答

(楼上都在说些什么。。。以下正确答案)

说在前面:
一般不会把事件绑定到document

假设你的问题是这样:

$('body').on('click', function(event) {
    /* some code */
});
$('body').on('click', '[data-btn-rank]', function(event) {
    /* some code */        
});

共同点
Function对象都是绑定在body元素上

不同点(即区别):
前者:点击body时触发
后者:点击[data-btn-rank]元素,冒泡到body时触发

以上。

selector:一个选择器字符串用于过滤器的触发事件的选择器元素的后代。如果选择的< null或省略,当它到达选定的元素,事件总是触发。

clipboard.png

当body是异步加载的页面时候,用document方法才可以

在某些情况异步加载 body,比如 rails 的 turbolinks,第二个可能就会失效,常规的

$(obj).on('click', function() {
  xxxx
})

也是可能失效或者多次绑定的,但是绑定在 document 上就不会有问题。


实测了一下,turbolinks 下第二个写法会出问题,有没有解决方法不确定,因为我一直是绑定在 document 上。

$(document).on('click', '.article-title', function() {
  console.log('document')
})
$('body').on('click', '.article-title', function() {
  console.log('body')
})

效果是一样的。
document其实代表的是html标签所包围的区域,和body有本质区别,但是在实际的实现上其实这两种方法是差不多的,都是事件委托通常选择的元素。且第二个参数存在的时候.o()绑定事件是通过事件监听机制,也就是说给即便有[data-btn-rank]属性的元素还没有加载出来,也会在加载成功的时候绑定上。
而第一种方法事件是委托给document,在document上的click事件触发的时候会访问触发这个事件的源元素来执行相应事件,因此也是和有[data-btn-rank]属性的元素的加载与否不冲突的。
所以在实现上效果一样。

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