停止在实时元素上传播

我遇到了阻止事件传播的问题。 想象一下这种情况:

然后这段代码:

 (function(){ $('td.row').on('click', function(e){ if (! e.isPropagationStopped()) alert('Row clicked!'); }); $('table#test').on('click', 'img.live', function(e){ e.stopPropagation(); alert('Image clicked!'); }); $('td.row').html(''); })();​ 

每当单击图像时,都会触发两个事件。 我希望它只是在点击的元素触发事件。 我知道,既然它们已经存在,它们会在传播结束后被解雇但是,有没有解决办法?

据我所研究,两个事件实际上是相同的,但srcElementHTMLTableCellElementHTMLImageElement 。 这种跨浏览器是否一致?

我已经在jsFiddle中放了一个演示,以防你想要观看。

这是一个演示

问题是事件必须爬到父级才能找到的处理程序。 因此它必须通过

并立即触发其处理程序,因为它不是委托处理程序。

 *click* ,-----------------> (1) fire direct td handler img -> td -> tr -> table '----> (2) fire delegated img handler X<---- (3) e.stopPropagation() //too late! 

防止double事件的一种方法是将

的处理程序添加到表中。 然后jQuery将评估两个处理程序,从最深的事件开始,如果这些处理程序中的任何一个具有e.stopPropagation() ,则更高的事件将不会触发。

 $('table#test').on('click', 'img.live', function(e){ e.stopPropagation(); alert('Image clicked!'); }); $('table#test').on('click','td.row', function(e){ alert('Row clicked!'); }); *click* img -> td -> tr -> table '----> (1) fire delegated img handler X<---- (2) e.stopPropagation() '----> (3) fire delegated td handler //never gets fired 

也许我错了,但你不能在这里使用事件授权吗?

 (function(){ $('#test').on('click', function(e){ if ( !/img$/i.test((e.target || e.eventSrc).nodeName)){ alert('row clicked'); } else { alert('image clicked'); } }); $('td.row').html(''); })();​ 

它可以为您节省传播的麻烦。 这是一个jsfiddle