2009-09-02 107 views
218

我目前正在使用jQuery使div可點擊,並在這個div我也有錨點。我遇到的問題是,當我點擊一個錨點時,兩個點擊事件都會觸發(對於div和錨點)。如何防止單擊錨點時觸發div的onclick事件?如何防止父母的onclick事件在點擊子錨時觸發?

這裏是斷碼:

的JavaScript

var url = $("#clickable a").attr("href"); 

$("#clickable").click(function() { 
    window.location = url; 
    return true; 
}) 

HTML

<div id="clickable"> 
    <!-- Other content. --> 
    <a href="http://foo.com">I don't want #clickable to handle this click event.</a> 
</div> 

回答

305

活動泡沫在其中一個點擊事件已附加了DOM的最高點。因此,在您的示例中,即使您在div中沒有​​任何其他可顯式單擊的元素,div的每個子元素都會將其單擊事件向上鼓起,直到DIV的click事件處理程序捕獲它爲止。

有兩個解決方案是檢查誰確實發起了事件。 jQuery的傳遞一個EventArgs對象隨着事件:

$("#clickable").click(function(e) { 
    var senderElement = e.target; 
    // check if sender is the DIV element e.g. 
    // if($(e.target).is("div")) { 
    window.location = url; 
    return true; 
}); 

您還可以將一個click事件處理程序,以你的鏈接,告訴他們stop event bubbling自己的處理程序後,執行:

$("#clickable a").click(function(e) { 
    //do something 
    e.stopPropagation(); 
}) 
+0

很好的答案。很高興知道也有選擇。 – 2009-09-02 17:42:22

+1

+1!用stopPropagation附加點擊處理程序是一個非常好的技巧,謝謝! – Thomas 2012-03-27 12:45:05

+1

如果你有一堆你想阻止傳播的元素,你可以找到他們的父元素,並防止它在那裏冒泡。因此,而不是截取div中的所有鏈接讓我們舉個例子 - 即使是在div上攔截點擊並阻止它進一步上升,然後設置好。 – sucitivel 2012-11-09 15:28:54

74

使用stopPropagation方法,看一個例子:

$("#clickable a").click(function(e) { 
    e.stopPropagation(); 
}); 

如jQuery的文檔說:

stopPropagation方法阻止事件向上冒泡的DOM樹 ,防止任何父處理程序從被通知的事件。

請記住,它不防止他人偵聽器來處理該事件(例如,一個按鈕的點擊多次處理程序),如果不是預期的效果,必須使用stopImmediatePropagation代替。

+0

+1這個是我正在尋找的完美答案。 – James 2010-07-07 23:39:14

-5
<a onclick="return false;" href="http://foo.com">I want to ignore my parent's onclick event.</a> 
+4

這也可以防止鏈接導航。 – 2009-09-02 17:28:46

+0

是的,還是不需要?或者需要成爲nevegar? – 2009-09-02 18:12:32

+2

嗯.. Nevegar誰? – mystrdat 2013-03-20 14:32:20

-2

添加a如下:

<a href="http://foo.com" onclick="return false;">....</a> 

或單擊處理return false;#clickable,如:

$("#clickable").click(function() { 
     var url = $("#clickable a").attr("href"); 
     window.location = url; 
     return false; 
    }); 
1

您需要停止事件到達(冒泡)父(div)。 查看關於冒泡的部分here以及jQuery特定的API信息here

+0

很酷。感謝關於事件冒泡的信息。 – 2009-09-02 17:40:07

-2

所有的解決方案都很複雜,而且是jscript。這是最簡單的版本:

var IsChildWindow=false; 

function ParentClick() 
{ 
    if(IsChildWindow==true) 
    { 
     IsChildWindow==false; 
     return; 
    } 
    //do ur work here 
} 


function ChildClick() 
{ 
    IsChildWindow=true; 
    //Do ur work here  
} 
+3

我認爲你在「IsChildWindow == false;」行中犯了一個錯誤。 - 不應該是「IsChildWindow = false;」? – 2012-01-26 12:31:13

6

如果您在點擊DIV多個元素,你應該這樣做:

$('#clickable *').click(function(e){ e.stopPropagation(); }); 
0

要指定一些子元素作爲不可點擊寫CSS層次結構中的示例下面。

在這個例子中,我停止傳播任何元素(*)內TD內TR表內與類「.subtable」

$(document).ready(function() 
{  
    $(".subtable tr td *").click(function (event) 
    { 
     event.stopPropagation(); 
    }); 

}); 
32

這裏我給大家在那裏尋找一個非jQuery的解決方案代碼(純JavaScript)

document.getElementById("clickable").addEventListener("click", function(e){ 
    e = window.event || e; 
    if(this === e.target) { 
     // put your code here 
    } 
}); 

您的代碼不會被執行,如果點擊了父母的孩子的

+1

這對我有用,我需要一個非JS/jQuery解決方案。 10倍! – 2016-09-27 14:08:19

+0

謝謝,你節省了我的時間 – 2016-11-17 05:23:54

7

使用return false;e.stopPropogation();不會讓福進一步執行的代碼。它會在這一點停止流動。

+0

是的,這很重要 - 自己碰到了這個。但是上面Rex的答案很有幫助 - 可以獲取被點擊的元素,並且在某些情況下,在您嘗試停止的邏輯中使用它。 .target.nodeName也有助於清楚瞭解所點擊的內容。 – Watercayman 2016-05-09 20:33:14

8

你也可以試試這個

$("#clickable").click(function(event) { 
    var senderElementName = event.target.tagName.toLowerCase(); 
    if(senderElementName === 'div') 
    { 
     // do something here 
    } 
    else 
    { 
     //do something with <a> tag 
    } 
}); 
+0

不錯的訣竅!這節省了我的時間!謝謝 – 2016-07-22 15:01:55

1

寫作如果有人需要(爲我工作):

event.stopImmediatePropagation() 

this解決方案。

4

如果您不打算在任何情況下與內部元素進行交互,那麼CSS解決方案可能對您有用。

內部元件/ S正好被設置爲pointer-events: none

你的情況:

.clickable > a { 
    pointer-events: none; 
} 

或一般地針對所有的內部元素:

.clickable * { 
    pointer-events: none; 
} 

這很容易破解救了我很多用ReactJS開發的時間

瀏覽器支持牛逼可以在這裏找到:http://caniuse.com/#feat=pointer-events

2

下面是使用一個例子角2+

例如,如果你想,如果用戶點擊它外面關閉一個模態分量:

// Close the modal if the document is clicked. 

@HostListener('document:click', ['$event']) 
public onDocumentClick(event: MouseEvent): void { 
    this.closeModal(); 
} 

// Don't close the modal if the modal itself is clicked. 

@HostListener('click', ['$event']) 
public onClick(event: MouseEvent): void { 
    event.stopPropagation(); 
}