0

我在停止事件传播时遇到问题。想象一下这个场景:

<table id="test">
    <tbody>
        <tr>
            <td class="row"> </td>
            <td class="row"> </td>
            <td class="row"> </td>
            <td class="row"> </td>
            <td class="row"> </td>
        </tr>
        <tr>
            <td class="row"> </td>
            <td class="row"> </td>
            <td class="row"> </td>
            <td class="row"> </td>
        </tr>
    </tbody>
</table>​

然后这段代码:

(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('<img src="http://fc03.deviantart.net/fs71/f/2011/161/f/c/nyan_cat_avatar_by_oxoxnaminemayxoxo-d3il6gm.gif" class="live">');
})();​

每当单击图像时,都会触发两个事件。我希望它只是触发单击元素上的事件。我知道,由于它们是实时的,因此一旦传播结束,它们就会被解雇,但是,有什么解决方法吗?

据我调查,这两个事件实际上是相同的,但从srcElement变为。这个跨浏览器是否一致?HTMLTableCellElementHTMLImageElement

我已经在jsFiddle中放了一个演示,以防您想观看实际操作。

4

2 回答 2

4

这是一个演示

问题是事件必须爬到父级才能找到<img>. 所以它必须通过<td>并立即触发它的处理程序,因为它不是委托处理程序。

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

防止双重事件的一种方法是将<td>' 处理程序也添加到表中。然后 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
于 2012-05-20T10:32:14.480 回答
1

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

(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('<img src="'+
                     'http://fc03.deviantart.net/fs71/f/2011/'+
                     '161/f/c/nyan_cat_avatar_by_'+
                     'oxoxnaminemayxoxo-d3il6gm.gif" class="live">');
})();​

它为您省去了传播的麻烦。这是一个jsfiddle

于 2012-05-20T10:39:49.283 回答