Как предотвратить включение родительского события onclick при нажатии на дочерний якорь?

В настоящее время я использую jQuery, чтобы сделать div clickable, и в этом div у меня также есть привязки. Проблема, с которой я сталкиваюсь, заключается в том, что когда я нажимаю на якорь, срабатывают оба события щелчка (для div и привязки). Как предотвратить событие div onclick при стрельбе при нажатии на якорь?

Здесь сломанный код:

JavaScript

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

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

HTML

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

Ответ 1

Событие пузырится до самой высокой точки в DOM, в которой было добавлено событие клика. Таким образом, в вашем примере, даже если у вас не было каких-либо других явно изменяемых элементов в div, каждый дочерний элемент div будет пузырить их событие click до DOM до тех пор, пока обработчик события DIV не поймает его.

Есть два варианта решения этой проблемы - проверить, кто на самом деле инициировал событие. 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;
});

Вы также можете присоединить обработчик события клика к своим ссылкам, которые говорят им прекратить пузырьки событий после выполнения их собственного обработчика:

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

Ответ 2

Используйте метод stopPropagation, см. пример:

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

Как сказано в jQuery Docs:

stopPropagation метод предотвращает появление пузырьков в DOM дерево, предотвращающее уведомление родительских обработчиков о событии.

Имейте в виду, что не позволяет другим слушателям обрабатывать это событие (например, более одного обработчика кликов для кнопки), если это не является желаемым эффектом, вы должны использовать stopImmediatePropagation вместо этого.

Ответ 3

Здесь мое решение для всех, кто ищет не-jQuery-код (чистый javascript)

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

Ваш код не будет выполнен, если нажать на родительские дочерние элементы

Ответ 4

вы также можете попробовать это

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

Ответ 5

Если вы в любом случае не собираетесь взаимодействовать с внутренним элементом /s, то вам может быть полезно решение CSS.

Просто установите внутренний элемент /s на pointer-events: none

в твоем случае:

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

или для цели всех внутренних элементов:

.clickable * {
    pointer-events: none;
}

Этот легкий взлом сэкономил мне много времени при разработке с помощью ReactJS

Поддержка браузера можно найти здесь: http://caniuse.com/#feat=pointer-events

Ответ 6

Использование return false; или e.stopPropogation(); не позволит выполнить дальнейший код. Он остановит поток в этой точке.

Ответ 7

Если у вас есть несколько элементов в интерактивном div, вы должны сделать это:

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

Ответ 8

Написание, если кому-то нужно (работал у меня):

event.stopImmediatePropagation()

Из этого решения.

Ответ 9

Здесь пример с использованием Angular 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();
}

Ответ 10

Вам нужно остановить событие от достижения (пузырька) родителя (div). См. Раздел о пузырях здесь и jQuery-специфическая информация об API здесь.

Ответ 11

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>

Ответ 12

Чтобы указать некоторый вспомогательный элемент как unclickable, пишите иерархию css, как в приведенном ниже примере.

В этом примере я прекращаю распространение любых элементов (*) внутри td внутри tr внутри таблицы с классом ".subtable"

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

});

Ответ 13

Если у кого-то была эта проблема с использованием React, я решил это.

СКС:

#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; }

Компонент render():

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

Добавлением функции onClick для дочернего модального (content div) событий щелчка мыши не удается достичь функции "closeLogin" родительского элемента.

Это сделало трюк для меня, и я смог создать модальный эффект с двумя простыми div.

Ответ 14

ignoreParent() - это чистое решение JavaScript.

Он работает в качестве промежуточного слоя, который сравнивает координаты щелчка мыши с координатами дочернего элемента/элементов. Два простых шага реализации:

1. Поместите код ignoreParent() на свою страницу.

2. Вместо родительского оригинала onclick = "parentEvent();" , записывать:

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

Вы можете передавать идентификаторы любого количества дочерних элементов в функцию и исключать другие.

Если вы щелкнули по одному из дочерних элементов, родительское событие не сработает. Если вы щелкнули по родительскому элементу, но не по дочернему элементу [предоставляется в качестве аргументов], родительское событие вызывается.

код ignoreParent() на Github

Ответ 15

Встроенная альтернатива:

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

Ответ 16

добавить 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;
   });

Ответ 17

Все решение сложное и jscript. Вот простейшая версия:

var IsChildWindow=false;

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


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

Ответ 18

<a onclick="return false;" href="#" onclick="location.href='http://foo.com'; return false;">I want to ignore my parent onclick event.</a>