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!

二重イベントを防ぐ 1 つの方法は、<td>のハンドラーもテーブルに追加することです。次に、jQuery は 2 つのハンドラーを評価し、最も深いイベントから開始します。これらのハンドラーのいずれかに がある場合、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 に答える