点击事件按钮是否发送图标作为目标?

我有一个非常类似的问题: “Jquery’点击’当按钮上没有触发按钮时”但该post的分辨率并没有为我提供解决方案,所以我认为可能会发生一些不同的事情。

关键问题是我有一个带有图标的按钮。 当我点击按钮(例如文本)时,事件目标是按钮元素; 但是当我点击图标时,事件目标就是图标对象。 不幸的是,这非常烦人,因为我将数据值存储在我想要访问的按钮上。

这是HTML:

  

这是Javascript:

 function sendVote(event) { var $btn = $(event.target); console.log(parseInt($btn.data('vote')); console.log($btn.prop('tagName')); } $('body').on('click', 'button.vote-button', sendVote); 

单击文本(“Up Vote!”或“Down Vote!”)会产生以下控制台输出:

 1 BUTTON -1 BUTTON 

单击图标(等)将导致以下控制台输出:

 NaN I NaN I 

即使我已经使用选择器“button.vote-button”在元素上注册了句柄。 有谁知道为什么会这样? 我不想必须为图标提供数据属性。

它是由事件传播引起的。 单击按钮内的图标,以便click事件通过DOM从图标向上传播到按钮,一直向上传播到文档。 这会导致您的click事件处理程序代码被执行。

如果问题是每次代码运行时你只想要按钮的引用,但是当你点击图标而不是文本时仍然希望它被触发,你只需要使用this而不是event.target

 var $btn = $(this); ... 

jQuery将确保它始终引用按钮,即使实际的event.target元素是其中的元素。

使用event.currentTarget ,它始终是侦听事件的对象; event.target是接收事件的实际目标,在这种情况下不是你想要的,因为它可能是图标。

使用event.currentTarget如果用户点击图标,它会将事件冒泡到对象侦听器,这是您案例中的按钮。 如果用户单击该按钮,它仍然可以工作,因为对象监听器再次是您的按钮。

更新这个因为$(event.target)并不总是button ,你必须按照建议使用三元运算符或者用$(this)替换$(event.target) ,它总是在选择器的上下文中button

 function sendVote(event) { event.stopPropagation(); var $btn = $(event.target).is('button') ? $(event.target) : $(event.target).parent(); console.log(parseInt($btn.data('vote'))); console.log($btn.prop('tagName')); } $(function () { $('body').on('click','button.vote-button', sendVote); }); 

演示小提琴


或者使用$(this) ,它总是button因为事件被绑定到它,如果你点击它的任何子节点,那么event将冒泡到dom树并且绑定到按钮的事件被执行:

 function sendVote(event) { var $btn = $(this); // <-----------------change just here console.log(parseInt($btn.data('vote'))); console.log($btn.prop('tagName')); } 

如果标记名是I,那么只需检查函数内部,如果是,则将父项作为$ btn。 http://jsfiddle.net/jFIT/qZgYU/3/

 $('body').on('click', 'button.vote-button', function() { var $btn = $(this).prop('tagName').toLowerCase() == "i" ? $(this).parent() : $(this); console.log(parseInt($btn.data('vote'))); console.log($btn.prop('tagName')); });