jquery stop child löst ein übergeordnetes Ereignis aus


208

Ich habe eine Div, an die ich eine onclickVeranstaltung angehängt habe. In diesem Div gibt es ein Tag mit einem Link. Wenn ich auf den Link onclickklicke, wird auch das Ereignis vom div ausgelöst. Wie kann ich dies deaktivieren, damit beim Klicken auf den Link onclicknicht das Div ausgelöst wird?

Skript:

$(document).ready(function(){
    $(".header").bind("click", function(){
         $(this).children(".children").toggle();
    });
})

HTML Quelltext:

<div class="header">
    <a href="link.html">some link</a>
    <ul class="children">
        <li>some list</li>
    </ul>
</div>

Antworten:


411

Mach das:

$(document).ready(function(){
    $(".header").click(function(){
        $(this).children(".children").toggle();
    });
   $(".header a").click(function(e) {
        e.stopPropagation();
   });
});

Wenn Sie mehr über .stopPropagation () erfahren möchten, klicken Sie hier .


2
wenn es jemand hilft, ersetzte ich $(".header a")mit $(".header *")und bekam jedes Kind ausgewählt (div, Formulare, Eingang, etc).
aldo.roman.nurena

1
e.stopPropagation (); muss in der ersten Zeile geschrieben werden, es sei denn, es funktioniert nicht!
Ehsan

2
rel
Leider

5
Die Antwort von xr280xr unten ist viel besser, da sie mögliche Ereignisse der Kinder nicht beeinträchtigt.
Alexander Jank

1
Sie schaffen mehr Probleme als Sie lösen. Stellen Sie sich Plugins von Drittanbietern vor, die das Klickereignis auf das Dokumentelement abhören. Sie werden nie über diese Klicks Bescheid wissen. Siehe den Kommentar zum Leuchtkasten.
Salman A

98

Oder, anstatt einen zusätzlichen Event - Handler mit einem anderen Handler zu verhindern, können Sie das verwenden Ereignisobjekt Argument zu Ihrem Click - Ereignishandler übergeben , um zu bestimmen , ob ein Kind geklickt wurde. targetwird das angeklickte Element sein und currentTargetwird das .header div sein:

$(".header").click(function(e){
     //Do nothing if .header was not directly clicked
     if(e.target !== e.currentTarget) return;

     $(this).children(".children").toggle();
});

8
Für mich ist dies eine elegantere Lösung, da Sie nicht jedem untergeordneten Element ein explizites PreventDefault () hinzufügen müssen.
Ryan Griggs

5
Und es funktioniert, wenn Sie im Gegensatz zur akzeptierten Antwort unabhängige Ereignisse für ein Kind haben. Auf jeden Fall sauberer und bessere Lösung
BozanicJosip

2
In den meisten Fällen wird Ihnen das nichts ausmachen, aber wenn Sie aus irgendeinem Grund IE6-8 unterstützen müssen, haben sie dies nichtcurrentTarget . Eine Problemumgehung besteht darin, sie durch zu ersetzen this, wie in einer anderen Antwort vorgeschlagen .
Alexander Jank

Dies ist eine sauberere Lösung, als einen zusätzlichen Listener so einzustellen, dass nur Klicks abgefangen werden.
Micros

Dieser Code funktionierte besser für mich. var target = $ (e.target); if (! target.is ("span")) return; `
Cr1xus

17

Besser durch Verwendung von on () mit Verkettung wie,

$(document).ready(function(){
    $(".header").on('click',function(){
        $(this).children(".children").toggle();
    }).on('click','a',function(e) {
        e.stopPropagation();
   });
});

4

Die Antworten hier nahmen die Frage des OP zu wörtlich. Wie können diese Antworten zu einem Szenario erweitert werden, in dem es VIELE untergeordnete Elemente gibt, nicht nur ein einzelnes <a>Tag? Hier ist eine Möglichkeit.

Angenommen, Sie haben eine Fotogalerie mit einem verdunkelten Hintergrund und die im Browser zentrierten Fotos. Wenn Sie auf den schwarzen Hintergrund klicken (aber nichts darin), soll die Überlagerung geschlossen werden.

Hier ist ein möglicher HTML-Code:

<div class="gallery" style="background: black">
    <div class="contents"> <!-- Let's say this div is 50% wide and centered -->
        <h1>Awesome Photos</h1>
        <img src="img1.jpg"><br>
        <img src="img2.jpg"><br>
        <img src="img3.jpg"><br>
        <img src="img4.jpg"><br>
        <img src="img5.jpg">
    </div>
</div>

Und so würde das JavaScript funktionieren:

$('.gallery').click(
    function()
    {
        $(this).hide();
    }
);

$('.gallery > .contents').click(
    function(e) {
        e.stopPropagation();
    }
);

Dadurch werden die Klickereignisse von Elementen innerhalb .contentsjeder Recherche gestoppt, .gallerysodass die Galerie nur geschlossen wird, wenn Sie in den ausgeblendeten schwarzen Hintergrundbereich klicken, nicht jedoch, wenn Sie in den Inhaltsbereich klicken. Dies kann auf viele verschiedene Szenarien angewendet werden.


4

Ich stolperte über diese Frage und suchte nach einer anderen Antwort.

Ich wollte verhindern, dass alle Kinder die Eltern auslösen.

JavaScript:

document.getElementById("parent").addEventListener("click",  function (e) {
    if (this !== event.target) return;
    // Do something
});

jQuery:

$("#parent").click(function () {
    // Do something
}).children().on("click", function (e) {
    e.stopPropagation();
});

0

Oder dieses:

$(document).ready(function(){
    $(".header").click(function(){
        $(this).children(".children").toggle();
    });
   $(".header a").click(function(e) {
        return false;
   });
});

2
@ Halcyon991 e wird in beiden Richtungen durch Argumente übergeben, e ist nur eine Referenz
qodeninja

@qodeninja Ja, aber ein unnötiger Charakterzusatz, wenn er nicht verwendet wird.
Halcyon991

Es macht keinen Sinn, return falseeinen Link hinzuzufügen , er sollte anklickbar sein.
eapo

0

Die einfachste Lösung besteht darin, den Kindern dieses CSS hinzuzufügen:

.your-child {
    pointer-events: none;
}

Ich brauchte dies für das unerwünschte Schriftart-Tag, das von Wordpress hinzugefügt wurde, und es funktionierte für mich
Ndm Gjr

-1

Ein kurzer Weg, dies zu tun:

$('.header').on('click', function () {
    $(this).children('a').on('click', function(e) {
        e.stopPropagation();
        $(this).siblings('.children').toggle();
    });
});

Aber ... Dies macht nichts, wenn Sie auf die Überschrift klicken.
Liora Haydont

Jedes Mal, wenn Sie auf die Kopfzeile klicken, wird den untergeordneten Elementen ein neues Klickereignis hinzugefügt ('a').
Frank Forte
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.