Jak zapobiec uruchomieniu zdarzenia onclick rodzica po kliknięciu zakotwiczenia dziecka?

Obecnie używam jQuery aby zrobić div klikalny i w tym div mam również anchory. Problem, na który wpadam, polega na tym, że po kliknięciu na kotwicę uruchamiają się oba zdarzenia kliknięcia (dla div I kotwicy). Jak zapobiec uruchomieniu zdarzenia onclick div po kliknięciu kotwicy?

Oto złamany kod:

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>
Author: Jonathon Watney, 2009-09-02

22 answers

Zdarzenia bańka do najwyższego punktu w DOM, w którym zdarzenie kliknięcie zostało dołączone. Tak więc w twoim przykładzie, nawet jeśli nie masz żadnych innych jawnie klikalnych elementów w div, każdy element potomny div będzie bąbelkował swoje Zdarzenie kliknięcia aż do momentu, gdy uchwyt zdarzenia kliknięcia DIV go złapie.

Istnieją dwa rozwiązania, aby sprawdzić, kto faktycznie był inicjatorem zdarzenia. jQuery przekazuje obiekt eventargs wraz ze zdarzeniem:

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

Możesz także Dołącz obsługę zdarzenia kliknięcia do linków, które każą im zatrzymać bulgotanie zdarzenia po wykonaniu własnego programu obsługi:

$("#clickable a").click(function(e) {
   // Do something
   e.stopPropagation();
});
 490
Author: Rex M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-13 20:19:36

Użyj metody stopropagacji , patrz przykład:

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

Jak powiedział jQuery Docs:

stopPropagation metoda zapobiega bąbelkowaniu się elementu DOM przez zdarzenie drzewa, uniemożliwiając jakimkolwiek opiekunom rodzicielskim powiadomienie o zdarzeniu.

Należy pamiętać, że to nie uniemożliwia innym słuchaczom obsługę tego zdarzenia (np. więcej niż jedno kliknięcie przycisku), jeśli nie jest to pożądany efekt, musisz zamiast tego użyć stopImmediatePropagation.

 108
Author: Cleiton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-04 19:33:29

Oto moje rozwiązanie dla wszystkich, którzy szukają kodu nie - jQuery (czystego javascript)

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

Twój kod nie zostanie wykonany, jeśli klikniesz na potomstwo rodzica

 51
Author: Sabaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-07 18:53:19

Jeśli w żadnym wypadku nie zamierzasz wchodzić w interakcję z elementami wewnętrznymi, wtedy rozwiązanie CSS może być dla Ciebie przydatne.

Po prostu ustaw Wewnętrzny element/y na pointer-events: none

W Twoim przypadku:

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

Lub kierować wszystkie wewnętrzne elementy ogólnie:

.clickable * {
    pointer-events: none;
}

Ten prosty hack zaoszczędził mi dużo czasu podczas tworzenia z ReactJS

Wsparcie dla przeglądarki można znaleźć tutaj: http://caniuse.com/#feat=pointer-events

 19
Author: Hooman Askari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-04 09:07:13

Możesz również spróbować tego

$("#clickable").click(function(event) {
   var senderElementName = event.target.tagName.toLowerCase();
   if(senderElementName === 'div')
   {
       // do something here 
   } 
   else
   {
      //do something with <a> tag
   }
});
 16
Author: Rashad Valliyengal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-16 10:50:46

Inline Alternatywa:

<div>
    <!-- Other content. -->
    <a onclick='event.stopPropagation();' href="http://foo.com">I don't want #clickable to handle this click event.</a>
</div>
 9
Author: Matt Wyeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-23 01:41:01

Jeśli masz wiele elementów w klikalnym div, powinieneś to zrobić:

$('#clickable *').click(function(e){ e.stopPropagation(); });
 8
Author: Ivan Ivković,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-11 10:15:32

Użycie return false; LUB e.stopPropogation(); nie pozwoli na dalsze wykonanie kodu. Zatrzyma przepływ w tym momencie.

 8
Author: Imamudin Naseem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-15 17:22:53

Pisanie Jeśli ktoś potrzebuje (u mnie działa):

event.stopImmediatePropagation()

Z tego rozwiązania.

 8
Author: Bahadir Tasdemir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:22

Oto przykład użycia Angular 2 +

Na przykład, jeśli chcesz zamknąć komponent modalny, jeśli użytkownik kliknie poza nim:

// 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();
}
 3
Author: Steve Brush,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-25 18:16:49

var inner = document.querySelector("#inner");
var outer = document.querySelector("#outer");
inner.addEventListener('click',innerFunction);
outer.addEventListener('click',outerFunction);

function innerFunction(event){
  event.stopPropagation();
  console.log("Inner Functiuon");
}

function outerFunction(event){
  console.log("Outer Functiuon");
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Pramod Kharade-Event with Outer and Inner Progration</title>
</head>
<body>
<div id="outer" style="width:100px;height:100px;background-color:green;">
  <div id="inner" style="width:35px;height:35px;background-color:yellow;"></div>
</div>
</body>
</html>
 2
Author: Pramod Kharade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-11 04:29:02

Musisz powstrzymać Zdarzenie przed dotarciem do rodzica (div). Zobacz część o bubbling tutaj , a informacje o jQuery-specific API Tutaj.

 1
Author: Matt Ball,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-02 17:27:27

Jeśli jest w inline context, w HTML spróbuj tak:

onclick="functionCall();event.stopPropagation();
 1
Author: Gleno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-14 23:32:08

Możesz sprawdzić, czy obiekt docelowy nie jest Twoim elementem div, a następnie wydać kolejne zdarzenie kliknięcia na rodzicu, po którym "wrócisz" z uchwytu.

$('clickable').click(function (event) {
    let div = $(event.target);
    if (! div.is('div')) {
       div.parent().click();
       return;
    }
    // Then Implement your logic here
}
 1
Author: nafiu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-15 16:57:16

Aby określić jakiś element podrzędny jako nie do kliknięcia, napisz hierarchię css jak w poniższym przykładzie.

W tym przykładzie Zatrzymuję propagację do dowolnych elementów ( * ) wewnątrz td wewnątrz tr wewnątrz tabeli z klasą ".subtable "

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

});
 0
Author: user3202819,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-16 14:18:09

Jeśli ktoś miał ten problem używając Reacta, oto jak go rozwiązałem.

Scss:

#loginBackdrop {
position: absolute;
width: 100% !important;
height: 100% !important;
top:0px;
left:0px;
z-index: 9; }

#loginFrame {
width: $iFrameWidth;
height: $iFrameHeight;
background-color: $mainColor;
position: fixed;
z-index: 10;
top: 50%;
left: 50%;
margin-top: calc(-1 * #{$iFrameHeight} / 2);
margin-left: calc(-1 * #{$iFrameWidth} / 2);
border: solid 1px grey;
border-radius: 20px;
box-shadow: 0px 0px 90px #545454; }

Component ' s render ():

render() {
    ...
    return (
        <div id='loginBackdrop' onClick={this.props.closeLogin}>
            <div id='loginFrame' onClick={(e)=>{e.preventDefault();e.stopPropagation()}}>
             ... [modal content] ...
            </div>
        </div>
    )
}

Poprzez dodanie funkcji onClick dla modalnego potomka (content div) zdarzenia kliknięcia myszy są uniemożliwione dotarcie do funkcji 'closeLogin' elementu nadrzędnego.

To mi pomogło i udało mi się stworzyć efekt modalny za pomocą 2 prostych divów.

 0
Author: Claudio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-25 06:29:56

IgnoreParent () jest czystym rozwiązaniem JavaScript.

Działa jako warstwa pośrednicząca, która porównuje współrzędne kliknięcia myszką ze współrzędnymi elementu / elementów potomnych.]}

1. umieść kod ignoreParent () na swojej stronie.

2. zamiast oryginału rodzica onclick= " parentEvent();", Napisz:

onclick="ignoreParent(['parentEvent()', 'child-ID']);"

Można przekazać ID dowolnej liczby elementów potomnych do funkcji i wykluczyć i inni

Jeśli klikniesz jeden z elementów potomnych, Zdarzenie rodzic nie zostanie wywołane. Jeśli klikniesz na rodzica, ale nie na żadnym z elementów potomnych [podanych jako argumenty], Zdarzenie rodzica zostanie wywołane.

IgnoreParent () kod na Github

 0
Author: Fom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-16 15:16:24

e.stopPropagation() jest poprawnym rozwiązaniem, ale w przypadku, gdy nie chcesz dołączyć żadnej obsługi zdarzeń do wewnętrznej kotwicy, możesz po prostu dołączyć tę obsługę do zewnętrznego div:

e => { e.target === e.currentTarget && window.location = URL; }
 0
Author: govizlora,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-11 22:51:29

Jeśli element potomny zostanie kliknięty, zdarzenie zostanie przeniesione do elementu nadrzędnego i zdarzenia.cel != = event.currentTarget.

Więc w swojej funkcji możesz to sprawdzić i wrócić wcześniej, tzn.:

var url = $("#clickable a").attr("href");
$("#clickable").click(function(event) {
    if ( event.target !== event.currentTarget ){
        // user clicked on a child and we ignore that
        return;
    }
    window.location = url;
    return true;
})
 0
Author: zıəs uɐɟəʇs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-05 16:20:23

Dodać a w następujący sposób:

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

Or return false; from Click handler for #clickable like:

  $("#clickable").click(function() {
        var url = $("#clickable a").attr("href");
        window.location = url;
        return false;
   });
 -3
Author: TheVillageIdiot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-02 17:27:20

Wszystkie rozwiązania są skomplikowane i JScript. Oto najprostsza wersja:

var IsChildWindow=false;

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


function ChildClick()
{
    IsChildWindow=true;
    //Do ur work here    
}
 -3
Author: ratnesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-01 22:12:29
<a onclick="return false;" href="http://foo.com">I want to ignore my parent's onclick event.</a>
 -5
Author: andres descalzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-02 17:25:13