2013-09-23 135 views
4

我有以下的HTML表:停止JS-事件傳播單擊

<table> 
    <tr> 
    <td> 
     Row 1 
    </td> 
    <td> 
     <!-- Hidden JSF-button --> 
     <button class="hide" /> 
    </td> 
    </tr> 
</table> 

當我點擊一個tr,我觸發隱藏按鈕點擊與JS:

$('table tr').on('click', function(e) { 
    var $button = $(this).find('button'); 
    console.log('trigger click on', $button); 

    $button.trigger('click'); 
}); 

單擊事件向上傳播,並會導致永無止境的循環(在這裏可以看到:http://codepen.io/anon/pen/kDxHy

一些SO搜索之後,很顯然,解決的辦法就是撥打event.stopPropagation
像這樣(在這裏可以看到:http://codepen.io/anon/pen/BnlfA):

$('table tr').on('click', function(e) { 
    var $button = $(this).find('button'); 

    // Prevent the event from bubbling up the DOM tree. 
    $button 
    .off('click') 
    .on('click', function(e) { 
     console.log('click'); 
     e.stopPropagation(); 

    return true; 
    }); 

    console.log('trigger click on', $button); 

    $button.trigger('click'); 
}); 

上述工程的解決方案。但它感覺像一個黑客,我不喜歡它。

是否需要在$button上註冊點擊處理程序才能撥打event.stopPropagation?有沒有更好的方法來阻止bubbeling的點擊事件?

+0

爲什麼你需要觸發點擊那個隱藏按鈕? – magyar1984

+0

該按鈕實際上是一個隱藏的JSF按鈕(http://www.mkyong.com/jsf2/jsf-2-button-and-commandbutton-example/)。當用戶點擊表格中的一行時,我觸發點擊按鈕,該按鈕調用支持控制器(服務器端)來設置一個值。 – nekman

+0

對不起,我不知道MVC是否涉及。我不確定這是否有幫助,但是當您觸發事件automaticaly時,event.target是什麼?如果它是按鈕,那麼你可以過濾它並在tr事件處理程序中停止傳播? – magyar1984

回答

0

更好的整體解決方案根本不是觸發click事件,而只是具有可以調用並封裝事件處理程序邏輯的單獨函數。

function doSomething(someArg) { 
    //do something 
} 

$('button').click(function() { 
    doSomething(/*pass whatever you want*/); 
}); 

$('table tr').on('click', function() { 
    doSomething(/*pass whatever you want*/); 
}); 

請注意,doSomething沒有一個事件處理程序的簽名,如(e)。這通常是一種很好的做法,只需傳遞函數來完成它自己的工作,而不是整個事件對象。這將簡化doSomething的實現並將其從事件對象完全解耦。

編輯:

對不起,但我需要手動觸發按鈕的點擊,當用戶點擊 在TR。請參閱我對@ magyar1984問題的評論。

在這種情況下,您可能已經找到了最好的解決方案,即在按鈕上附加事件偵聽器並呼叫stopPropagation。您還可以通過在元素上使用events數據來查看獲取所有單擊事件處理程序,但要注意,您將依賴jQuery內部部件,以便在將來的版本中可以打破代碼。

看看this question知道如何檢索事件處理程序。

+0

對不起,但我需要手動觸發按鈕點擊時,用戶點擊tr。請參閱我對@ magyar1984問題的評論。 – nekman

+0

@nekman我更新了答案。 – plalx

+0

謝謝,是的,我認爲解決方案必須是手動防止事件冒泡。我製作了一個可以用作防止冒泡的快捷方式的插件。 http://nekman.se/prevent-jquery-event-from-bubbling/ – nekman

0

我能夠通過更新codepen以下得到它只能註冊一次按鈕點擊:

var handleClick = function(e) { 
    var $button = $(this).find('button'); 
    console.log('trigger click on', $button); 

    $button.trigger('click'); 
}; 
$('button.hide').on('click',function(e){ 
    e.stopPropagation(); 
}); 

$(function() { 
    $('table tr') 
    .on('click', handleClick); 
}); 

但總的想法是申報上的按鈕onClick事件,並停止傳播那裏。

0

修改按鈕行爲,特別是在框架中,可能會導致一些意外問題。您可以向該行添加一個標誌並使用它來檢查是否應該點擊該按鈕。但是您必須知道自動生成的點擊次數,因此應該省略。

var handleClick = function(e) { 
    var $button = $(this).find('button'); 
    console.log('triggerring click on...', $button); 
    if (this.clicked !== true) { 
    console.log('and clicked!') 
    this.clicked = true; 
    $button.trigger('click'); 
    } else 
    this.clicked = false; 
}; 

下面的代碼:http://codepen.io/anon/pen/dJroL