jquery dừng sự kiện kích hoạt cha mẹ


208

Tôi có một div mà tôi đã đính kèm một onclicksự kiện. trong div này có một thẻ với một liên kết. Khi tôi nhấp vào liên kết, onclicksự kiện từ div cũng được kích hoạt. Làm thế nào tôi có thể vô hiệu hóa điều này để nếu liên kết được nhấp vào div onclickkhông bị bắn?

kịch bản:

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

Mã HTML:

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

Câu trả lời:


411

Làm cái này:

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

Nếu bạn muốn đọc thêm về .stopPropagation (), xem tại đây .


2
nếu nó giúp ai đó, tôi đã thay thế $(".header a")với $(".header *")và có bất kỳ đứa trẻ được lựa chọn (div, biểu mẫu, đầu vào, vv).
aldo.roman.nurena

1
e.stopPropagation (); phải được viết ở dòng đầu tiên, trừ khi nó không hoạt động!
ehsan

2
thật đáng buồn khi phương pháp này ngăn relhộp đèn được cấu hình hoạt động
eapo

5
Câu trả lời dưới đây của xr280xr tốt hơn nhiều, vì nó không can thiệp vào các sự kiện có thể xảy ra của trẻ em.
Alexander Jank

1
Bạn tạo ra nhiều vấn đề hơn bạn giải quyết. Hãy tưởng tượng các plugin của bên thứ ba lắng nghe sự kiện nhấp vào yếu tố tài liệu. Họ sẽ không bao giờ biết về những nhấp chuột đó. Xem bình luận về hộp đèn.
Salman A

98

Hoặc, thay vì có một trình xử lý sự kiện bổ sung để ngăn chặn một trình xử lý khác, bạn có thể sử dụng đối số Sự kiện đối tượng được chuyển đến trình xử lý sự kiện nhấp chuột của bạn để xác định xem một đứa trẻ có được nhấp hay không. targetsẽ là phần tử được nhấp và currentTargetsẽ là div .header:

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

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

8
Đối với tôi đây là một giải pháp thanh lịch hơn vì bạn không phải thêm một ngăn chặn rõ ràng () cho mọi phần tử con.
Ryan Griggs

5
Và nó hoạt động nếu bạn có các sự kiện độc lập trên trẻ em không giống như câu trả lời được chấp nhận. Giải pháp chắc chắn sạch hơn và tốt hơn
BozanicJosip

2
Trong hầu hết các trường hợp, bạn sẽ không quan tâm đến vấn đề này, nhưng nếu vì bất kỳ lý do gì bạn cần hỗ trợ IE6-8, họ không cócurrentTarget . Một cách giải quyết là thay thế nó this, như được đề xuất trong câu trả lời khác .
Alexander Jank

Đây là một giải pháp sạch hơn là thiết lập một trình nghe bổ sung để chỉ bắt các nhấp chuột.
Kính hiển vi

mã này hoạt động tốt hơn đối với tôi `var target = $ (e.target); if (! target.is ("span")) trở lại; `
Cr1xus

17

Cách tốt hơn bằng cách sử dụng on () với chuỗi như,

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

4

Các câu trả lời ở đây lấy câu hỏi của OP quá đúng theo nghĩa đen. Làm thế nào những câu trả lời này có thể được mở rộng thành một kịch bản có NHIỀU phần tử con, không chỉ là một <a>thẻ? Đây là một cách.

Giả sử bạn có một bộ sưu tập ảnh với nền bị bôi đen và các ảnh ở giữa trình duyệt. Khi bạn nhấp vào nền đen (nhưng không phải bất cứ thứ gì bên trong nó), bạn muốn lớp phủ đóng lại.

Đây là một số HTML có thể:

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

Và đây là cách JavaScript hoạt động:

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

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

Điều này sẽ dừng các sự kiện nhấp chuột từ các yếu tố bên trong .contentstừ mọi nghiên cứu .galleryđể thư viện sẽ chỉ đóng khi bạn nhấp vào khu vực nền đen mờ, nhưng không phải khi bạn nhấp vào khu vực nội dung. Điều này có thể được áp dụng cho nhiều kịch bản khác nhau.


4

Tôi vấp phải câu hỏi này, tìm kiếm một câu trả lời khác.

Tôi muốn ngăn chặn tất cả trẻ em kích hoạt cha mẹ.

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

Hoặc này:

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

2
@ Halcyon991 e được thông qua bằng bất kỳ cách nào thông qua các đối số, e chỉ là một tài liệu tham khảo
qodeninja

@qodeninja Vâng, nhưng một bổ sung nhân vật không cần thiết nếu nó không được sử dụng.
Halcyon991

Không có điểm thêm return falsevào liên kết, nó có thể được nhấp.
eapo

0

Giải pháp đơn giản nhất là thêm CSS này cho trẻ em:

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

Tôi cần cái này cho thẻ phông không mong muốn được thêm bởi Wordpress và nó hoạt động với tôi
Ndm Gjr

-1

Một cách ngắn hơn để làm điều đó:

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

Nhưng ... Điều này không làm gì khi nhấp vào tiêu đề.
Liora Haydont

Mỗi lần bạn nhấp vào tiêu đề, điều này sẽ thêm một sự kiện nhấp chuột mới cho trẻ em ('a').
Frank Forte
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.