2009-09-02 2 views
218

Ich verwende derzeit jQuery, um ein div anklickbar zu machen und in diesem div habe ich auch Anker. Das Problem, auf das ich stoße, ist, dass wenn ich auf einen Anker klicke, beide Klickereignisse (für das div und den Anker) auslösen. Wie verhindere ich, dass das Onclick-Ereignis des DIVs ausgelöst wird, wenn auf einen Anker geklickt wird?Wie verhindere ich, dass das Onclick-Ereignis eines Elternteils ausgelöst wird, wenn auf einen Child-Anker geklickt wird?

Hier ist der gebrochene Code:

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> 

Antwort

305

Ereignisse werden zum höchsten Punkt im DOM verschoben, an dem ein Klickereignis angehängt wurde. In Ihrem Beispiel würde also jedes untergeordnete Element des Bereichs selbst dann, wenn Sie keine anderen explizit anklickbaren Elemente im Bereich div hatten, sein Klickereignis über das DOM-Steuerelement hinausblasen, bis der Click-Ereignishandler des DIV es abfängt.

Es gibt zwei Lösungen, um zu überprüfen, wer das Ereignis tatsächlich ausgelöst hat. jQuery übergibt ein EventArgs mit dem Event-Objekt zusammen:

$("#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; 
}); 

Sie können auch einen Click-Ereignishandler Ihre Links anhängen, die sie nach ihren eigenen Handler stop event bubbling sagen ausführt:

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

Große Antwort. Gut zu wissen gibt es auch Optionen. –

+1

+1! Einen Klick-Handler mit stopPropagation anzuhängen, ist ein sehr netter Trick, danke! – Thomas

+1

Wenn Sie eine Reihe von Elementen haben, auf die Sie die Weiterleitung verhindern möchten, können Sie feststellen, dass das übergeordnete Element und der Kopf verhindern, dass es auch dort aufsteigt. Also, anstatt alle Links in einem div abzufangen, sagen wir zum Beispiel, fangen Sie einfach den Klick selbst auf das div selbst ab und verhindern Sie, dass es höher geht und Sie gesetzt sind. – sucitivel

74

Verwenden stopPropagation Methode, um ein Beispiel sehen:

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

sagte Wie durch jQuery Dokumente:

stopPropagation Methode verhindert das Ereignis aus sprudelt aus dem DOM Baum, Verhinderung jeglicher Mutter Handler des Ereignisses benachrichtigt zu werden.

Beachten Sie, dass es nicht andere Zuhörer verhindern, dass dieses Ereignis zu handhaben (ex. Mehr als ein Klick-Handler für eine Schaltfläche), wenn es nicht die gewünschte Wirkung, müssen Sie stopImmediatePropagation stattdessen verwenden.

+0

+1 dieses war die perfekte Antwort, die ich suchte. – James

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

Dies verhindert auch, dass die Verbindung navigiert. –

+0

Ja, oder nicht was benötigt wird ?. Oder muss nevegar sein? –

+2

Umm .. Nevegar wer? – mystrdat

-2

a wie folgt hinzufügen :

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

oder return false; von Handler klicken für #clickable wie:

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

Sie müssen das Ereignis stoppen, um das Elternelement (div) zu erreichen (zu bubbling). Sehen Sie den Teil über sprudelnde here und jQuery-spezifische API-Informationen here.

+0

Kühl. Danke für die Info zum Ereignissprudeln. –

-2

Alle Lösungen sind kompliziert und von jscript.Hier ist die einfachste Version:

var IsChildWindow=false; 

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


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

Ich denke, Sie haben einen Fehler in Zeile "IsChildWindow == false;" - sollte es nicht "IsChildWindow = false" sein? –

6

Wenn Sie mehrere Elemente in den klickbaren div haben, können Sie dies tun sollten:

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

Um etwas Unter Element angeben als unclickable die CSS-Hierarchie wie im Beispiel schreiben unten.

In diesem Beispiel halte ich Ausbreitung auf alle Elemente (*) innerhalb td innerhalb tr in einer Tabelle mit der Klasse „.subtable“

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

}); 
32

Hier ist meine Lösung für alle da draußen für einen nicht-jQuery suchen Code (reine Javascript)

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

Ihr Code wird nicht, wenn auf childs übergeordneten

+1

Dies funktionierte für mich, ich brauchte eine Nicht-JS/jQuery-Lösung. 10x! –

+0

Danke, du hast mir die Stunden gerettet –

7

Mit return false; oder e.stopPropogation(); erlauben nicht fu geklickt ausgeführt werden weiterer Code zum Ausführen. Es stoppt den Fluss an diesem Punkt selbst.

+0

Ja, das ist wichtig - ich bin selbst darauf gestoßen. Aber die obige Antwort von Rex ist hilfreich - kann das Element erhalten, auf das geklickt wurde, und in manchen Fällen verwenden Sie dies in der Logik, die Sie zu stoppen versuchen. .target.nodeName war auch hilfreich, um eine klare Vorstellung davon zu bekommen, was getroffen wurde. – Watercayman

8

können Sie auch versuchen, diese

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

netter Trick! das hat meine Zeit gerettet! Vielen Dank –

1

Schreiben, wenn jemand braucht (arbeitete für mich):

event.stopImmediatePropagation() 

Von this Lösung.

4

Wenn Sie auf keinen Fall mit dem inneren Element/s interagieren möchten, könnte eine CSS-Lösung für Sie nützlich sein.

Stellen Sie einfach das innere Element/s pointer-events: none

in Ihrem Fall:

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

oder alle inneren Elemente im Allgemeinen Ziel:

.clickable * { 
    pointer-events: none; 
} 

Diese einfache Hack hat mich gerettet viel Zeit während der Entwicklung mit ReactJS

Browser suppor http://caniuse.com/#feat=pointer-events

2

Hier ist ein Beispiel unter Verwendung von Angular 2+

Zum Beispiel, wenn Sie wollen eine Modal-Komponente schließen, wenn der Benutzer außerhalb davon klickt: t könnte hier gefunden werden

// 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(); 
}