jquery berhenti memicu anak acara orangtua

208

Saya memiliki div yang telah saya lampirkan onclickacara. di div ini ada tag dengan tautan. Ketika saya mengklik tautan onclickacara dari div juga dipicu. Bagaimana saya bisa menonaktifkan ini sehingga jika tautan diklik pada div onclicktidak dipecat?

naskah:

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

kode html:

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

Jawaban:

412

Melakukan hal ini:

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

Jika Anda ingin membaca lebih lanjut tentang .stopPropagation (), lihat di sini .

Nick Craver
sumber
2
jika itu membantu seseorang, saya diganti $(".header a")dengan $(".header *")dan mendapatkan anak yang dipilih (div, formulir, masukan, dll).
aldo.roman.nurena
1
e.stopPropagation (); harus ditulis di baris pertama, kecuali jika tidak berfungsi!
ehsan
2
sayangnya metode ini mencegah rellightbox yang dikonfigurasi berfungsi
eapo
5
Jawaban di bawah ini oleh xr280xr jauh lebih baik, karena tidak mengganggu kemungkinan acara anak-anak.
Alexander Jank
1
Anda menciptakan lebih banyak masalah daripada yang Anda pecahkan. Bayangkan plugin pihak ketiga mendengarkan klik acara pada elemen dokumen. Mereka tidak akan pernah tahu tentang klik itu. Lihat komentar tentang lightbox.
Salman A
100

Atau, daripada memiliki pengendali event tambahan untuk mencegah pengendali lainnya, Anda bisa menggunakan argumen Object Event yang diteruskan ke pengendali event klik untuk menentukan apakah seorang anak diklik. targetakan menjadi elemen yang diklik dan currentTargetakan menjadi .header div:

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

     $(this).children(".children").toggle();
});
xr280xr
sumber
8
Bagi saya ini adalah solusi yang lebih elegan karena Anda tidak perlu menambahkan preventDefault eksplisit () ke setiap elemen anak.
Ryan Griggs
5
Dan itu berfungsi jika Anda memiliki acara independen tentang anak tidak seperti jawaban yang diterima. Solusi yang pasti lebih bersih dan lebih baik
BozanicJosip
2
Dalam sebagian besar keadaan Anda tidak akan peduli tentang ini, tetapi jika karena alasan apa pun Anda perlu mendukung IE6-8, mereka tidak memilikinyacurrentTarget . Solusinya adalah menggantinya dengan this, seperti yang disarankan dalam jawaban lain .
Alexander Jank
Ini adalah solusi yang lebih bersih daripada mengatur pendengar tambahan untuk hanya menangkap klik.
Micros
kode ini berfungsi lebih baik untuk saya `var target = $ (e.target); if (! target.is ("span")) kembali; `
Cr1xus
17

Cara yang lebih baik dengan menggunakan on () dengan chaining seperti,

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

Jawaban di sini mengambil pertanyaan OP terlalu harfiah. Bagaimana jawaban ini dapat diperluas menjadi skenario di mana ada elemen anak BANYAK, bukan hanya satu <a>tag? Ini satu cara.

Katakanlah Anda memiliki galeri foto dengan latar belakang pingsan dan foto-foto terpusat di browser. Saat Anda mengeklik latar belakang hitam (tetapi tidak apa pun di dalamnya), Anda ingin tutupnya ditutup.

Berikut ini beberapa HTML yang mungkin:

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

Dan inilah cara kerja JavaScript:

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

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

Ini akan menghentikan acara klik dari elemen di dalam .contentsdari setiap penelitian .gallerysehingga galeri akan ditutup hanya ketika Anda mengklik area latar belakang hitam yang pudar, tetapi tidak ketika Anda mengklik di area konten. Ini dapat diterapkan pada banyak skenario yang berbeda.

Gavin
sumber
4

Saya menemukan pertanyaan ini, mencari jawaban lain.

Saya ingin mencegah semua anak memicu orang tua.

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();
});
Daan
sumber
0

Atau ini:

$(document).ready(function(){
    $(".header").click(function(){
        $(this).children(".children").toggle();
    });
   $(".header a").click(function(e) {
        return false;
   });
});
pengguna719004
sumber
2
@ Halcyon991 e akan diteruskan dengan cara apa pun melalui argumen, e hanya referensi
qodeninja
@qodeninja Ya, tapi penambahan karakter yang tidak perlu jika tidak digunakan.
Halcyon991
Tidak ada gunanya menambahkan return falseke tautan, itu harus dapat diklik.
eapo
0

Solusi paling sederhana adalah menambahkan CSS ini ke anak-anak:

.your-child {
    pointer-events: none;
}
Dermaga
sumber
Saya membutuhkan ini untuk tag font yang tidak diinginkan ditambahkan oleh Wordpress dan itu bekerja untuk saya
Ndm Gjr
-1

Cara yang lebih singkat untuk melakukannya:

$('.header').on('click', function () {
    $(this).children('a').on('click', function(e) {
        e.stopPropagation();
        $(this).siblings('.children').toggle();
    });
});
Andreas 'aNdy' Berggreen
sumber
Tapi ... Ini tidak melakukan apa-apa saat mengklik header.
Liora Haydont
Setiap kali Anda mengklik tajuk, ini menambahkan acara klik baru untuk anak-anak ('a').
Frank Forte