jquery stop child เรียกเหตุการณ์ผู้ปกครอง


208

ฉันมี div ที่ฉันได้แนบonclickกิจกรรมไป ใน div นี้มีแท็กพร้อมลิงค์ เมื่อฉันคลิกลิงก์onclickกิจกรรมจาก div ก็จะถูกเรียกใช้ ฉันจะปิดการใช้งานสิ่งนี้ได้อย่างไรหากการเชื่อมโยงถูกคลิกที่ div onclickไม่ได้ถูกไล่ออก?

สคริปต์:

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

คำตอบ:


411

ทำเช่นนี้:

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

หากคุณต้องการอ่านเพิ่มเติมเกี่ยวกับ .stopPropagation () ดูที่นี่


2
ถ้ามันช่วยใครซักคนฉันจะแทนที่$(".header a")ด้วย$(".header *")และเลือกลูก ๆ (div, form, input, etc)
aldo.roman.nurena

1
e.stopPropagation (); จะต้องเขียนที่บรรทัดแรกยกเว้นว่าจะใช้งานไม่ได้!
ehsan

2
น่าเศร้าที่วิธีนี้ป้องกันไม่ให้relไลท์บ็อกซ์ที่ตั้งค่าไว้ทำงาน
eapo

5
คำตอบด้านล่างโดย xr280xr นั้นดีกว่ามากเพราะไม่ได้รบกวนกิจกรรมที่เป็นไปได้ของเด็ก ๆ
Alexander Jank

1
คุณสร้างปัญหามากกว่าที่คุณจะแก้ปัญหา ลองนึกภาพปลั๊กอินของบุคคลที่สามที่ฟังเหตุการณ์การคลิกในองค์ประกอบของเอกสาร พวกเขาจะไม่เคยรู้เกี่ยวกับการคลิกเหล่านั้น ดูความคิดเห็นเกี่ยวกับไลท์บ็อกซ์
Salman

100

หรือแทนที่จะมีตัวจัดการเหตุการณ์พิเศษเพื่อป้องกันตัวจัดการอื่นคุณสามารถใช้อาร์กิวเมนต์วัตถุเหตุการณ์ที่ส่งผ่านไปยังตัวจัดการเหตุการณ์การคลิกของคุณเพื่อตรวจสอบว่ามีการคลิกลูกหรือไม่ targetจะเป็นองค์ประกอบที่ถูกคลิกและcurrentTargetจะเป็น. header div:

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

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

8
สำหรับฉันนี่เป็นโซลูชันที่สง่างามกว่าเพราะคุณไม่จำเป็นต้องเพิ่ม PreventDefault () ที่ชัดเจนให้กับองค์ประกอบย่อยทั้งหมด
Ryan Griggs

5
และมันจะทำงานถ้าคุณมีเหตุการณ์ที่เป็นอิสระเกี่ยวกับเด็กซึ่งแตกต่างจากคำตอบที่ยอมรับ โซลูชันที่สะอาดและดีกว่าแน่นอน
BozanicJosip

2
ในกรณีส่วนใหญ่คุณจะไม่สนใจเกี่ยวกับเรื่องนี้ แต่ถ้าด้วยเหตุผลอะไรก็ตามที่คุณต้องการที่จะสนับสนุน IE6-8 พวกเขาไม่ได้มี currentTargetการแก้ปัญหาคือการแทนที่ด้วยthisตามที่แนะนำในคำตอบอื่น
Alexander Jank

นี่เป็นวิธีที่สะอาดกว่าการตั้งค่าผู้ฟังเพิ่มเติมเพื่อเพียงแค่จับคลิก
Micros

รหัสนี้ทำงานได้ดีขึ้นสำหรับ me` var target = $ (e.target); if (! target.is ("span")) return; `
Cr1xus

17

วิธีที่ดีกว่าโดยใช้บน ()กับการผูกมัดเช่น

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

4

คำตอบที่นี่ก็ตอบคำถามของ 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ดังนั้นแกลเลอรีจะปิดเฉพาะเมื่อคุณคลิกในพื้นที่พื้นหลังสีดำจาง ๆ แต่จะไม่หยุดเมื่อคุณคลิกในพื้นที่เนื้อหา สิ่งนี้สามารถนำไปใช้กับสถานการณ์ต่าง ๆ มากมาย


4

ฉันสะดุดกับคำถามนี้โดยมองหาคำตอบอื่น

ฉันต้องการป้องกันไม่ให้เด็กทุกคนเรียกพ่อแม่

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

หรือสิ่งนี้:

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

2
@ Halcyon991 e ได้รับการส่งผ่านอย่างใดอย่างหนึ่งผ่านการขัดแย้ง e เป็นเพียงการอ้างอิง
qodeninja

@ qodeninja ใช่ แต่เป็นการเพิ่มอักขระที่ไม่จำเป็นถ้าไม่ได้ใช้
Halcyon991

ไม่มีการเพิ่มจุดreturn falseลงในลิงก์ควรคลิกได้
eapo

0

ทางออกที่ง่ายที่สุดคือการเพิ่ม CSS นี้ให้กับเด็ก ๆ :

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

ฉันต้องการสิ่งนี้สำหรับแท็กตัวอักษรที่ไม่พึงประสงค์ซึ่งเพิ่มโดย Wordpress และมันก็ใช้ได้สำหรับฉัน
Ndm Gjr

-1

วิธีสั้น ๆ ที่จะทำ:

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

แต่ ... มันไม่ได้ทำอะไรเลยเมื่อคลิกที่ส่วนหัว
Liora Haydont

ทุกครั้งที่คุณคลิกที่ส่วนหัวนี่จะเป็นการเพิ่มกิจกรรมคลิกใหม่ให้กับลูก ๆ ('a')
Frank Forte
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.