2010-03-02 5 views
154

У меня есть div, к которому я присоединил событие onclick. в этом div есть тег со ссылкой. Когда я нажимаю на ссылку, также вызывается событие onclick из div. Как я могу отключить это, чтобы, если ссылка нажата на div onclick не уволен?jquery stop child triggering parent event

сценарий:

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

HTML код:

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

ответ

344

ли это:

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

Если вы хотите read more on .stopPropagation(), look here.

+2

, если это помогает кто-то, я заменил '$ (» заголовок ")' с '$ (".заголовок * ")' и получил выбранный дочерний элемент (div, forms, input и т. д.). –

+0

e.stopPropagation(); должно быть записано в первой строке, если оно не работает! – ehsan

+3

@ehsan Возможно, вы имели в виду: "или это не сработает »? –

0

Или это:

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

Отсутствует точка (e), если вы возвращаете false. – Halcyon991

+2

@ Halcyon991 e передается в любом случае через аргументы, e является просто ссылкой – qodeninja

+0

@qodeninja Да, но ненужное добавление символов, если оно не используется. – Halcyon991

15

Лучший способ с использованием on() с цепочки, как,

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

Ответы здесь взяли на вопрос OP слишком буквально. Как эти ответы могут быть расширены в сценарий, где есть МНОГО дочерних элементов, а не только один тег <a>? Вот один из способов.

Предположим, у вас есть фотогалерея с затемненным фоном и фотографиями, расположенными в центре браузера. Когда вы нажимаете черный фон (но ничего не внутри), вы хотите закрыть оверлей.

Вот некоторые возможные HTML:

<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> 

А вот как JavaScript будет работать:

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

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

Это остановит клики событие из элементов внутри .contents от каждого исследования .gallery поэтому галерея закроются только когда вы щелкаете в выцветшей области черного фона, но не при нажатии в области содержимого. Это может быть применено ко многим различным сценариям.

1

Более короткий способ сделать это:

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

Или, вместо того, дополнительный обработчик событий, чтобы предотвратить еще один обработчик, вы можете использовать Event Object аргумент, передаваемый в обработчик события щелчка, чтобы определить, является ли ребенок был нажат. target будет щелкнул элемент и currentTarget будет .header ДИВ:

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

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

Для меня это более элегантное решение, так как вам не нужно добавлять явное предупреждениеDefault() для каждого дочернего элемента. –

+1

И он работает, если у вас есть независимые события на ребенке в отличие от принятого ответа. Определенно более чистое и лучшее решение –

+2

В большинстве случаев вам это не пойдет, но если по какой-то причине вам необходимо поддерживать IE6-8, у них [не существует «currentTarget»] (https://developer.mozilla.org/en -US/документы/Web/API/Event/currentTarget). Обходной путь заключается в замене его на 'this', как предложено в [другом ответе] (http://stackoverflow.com/a/6411507/2737565). –

0

Я наткнулся на этот вопрос, в поисках другого ответа.

Я хотел предотвратить всех детей от запуска родителя.

Это самый простой, самый читаемый способ для этого:

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