Как при клике на потомка, не выполнять функцию родителя?

Здравствуйте.

Заданы две различные функции на клики по родителю и потомку.

<div class="parent">
        <div class="son"></div>
        <div class="son1"></div>
        <div class="son2"></div>
    </div>


$('.parent').click(function(){
    console.log('parentFn');
    });

 $('.son').click(function(){
    console.log('sonFn');
    });


Проблема в том, что при клике по потомку, происходит сразу обе функции.

Способ...
$('.parent:not(.son)').click(function(){
    console.log('sonFn');
    });

...не помогает

Как сделать, чтобы при клике по потомку, функция, заданная на родителя не выполнялась?
  • Вопрос задан
  • 7099 просмотров
Решения вопроса 4
nikolayshabalin
@nikolayshabalin
Автор профессиональных курсов в HTML Academy
Приветствую.

Изучите как работают события в DOM. Это очень полезно. Trust me. Они погружаются до элемента и потом всплывают. Вот хорошие примеры - learn.javascript.ru/event-bubbling

Вкратце, когда вы кликаете на DOM-ноду,
1. событие начинает свой путь от самого корневого элемента, от document,
2. доходит до кликнутого элемента, запускает обработчики если они есть на этом элементе
3. начинает всплывать, запуская обработчики на каждом элементе у которого есть обработчики на такой тип события, в данном примере click

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

<div class="parent">
    <div class="son">son</div>
    <div class="son1">son 1</div>
    <div class="son2">son 2</div>
</div>


$('.parent').on('click', function() {
    console.log('parent function');
});

$('.son').on('click', function(event) {
    event.stopPropagation();
    console.log('son function');
});


Что в данном случае происходит, событие опускается до $('.son'), запускает обработчик function(event) {...});, а event.stopPropagation(); запрещает событию click всплыть, то есть подняться до элемента $('.parent'), поэтому обработчики $('.parent') не запускаются.

Ещё бы хотел посоветовать меньше лезть/смотреть в DOM. Говорят это очень ресурсоемкие задачи, так родился Virtual DOM.

Что в вашем примере не так.

Вы сначала лезете в DOM за $('.parent'), а потом за $('.son').
Сохраняя $('.parent'), вы уже можете обратится к $('.son') без лазания в DOM.

То есть ваш пример выгоднее бы выглядел вот так

const $parent = $('.parent');
const $son = $parent.find('.son');

$parent.on('click', function() {
    console.log('parent function');
});

$son.on('click', function(event) {
    event.stopPropagation();
    console.log('son function');
});


Я понимаю, что в данном примере это вообще никак не отразится на производительности, но если ваше приложение чуть сложнее, чем этот пример, то профиты будут.
Ответ написан
baskserg
@baskserg
Better skills, better life.
$('.son').click(function(){
    console.log('sonFn');
    return false;
});
Ответ написан
dimovich85
@dimovich85 Куратор тега JavaScript
https://u-academy.net/
Вариант 1
$('.elem').click(function(e){
if($(e.target).is('.elem'){
alert(1);
}
});

Вариант 2
$('.elem').on('click', '.elem', function(e){
alert(1);
});
Клик в родителе происходит из-за всплытия событий, чтобы проверить, на ком именно произошел клик можно проверить e.target, или в jq, с помощью .on(), можно передать вторым параметром селектор, который будет использоваться для проверки, на ком именно произошло событие. То есть тоже самое, но немного короче.
Ответ написан
Комментировать
Eridani
@Eridani
Мимо проходил
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы