ทำอย่างไรให้คลิกเหตุการณ์มีผลเฉพาะกับแม่ DIV ไม่ใช่เด็ก ๆ


211

ฉันมี DIV ที่มีการแบ่งประเภทfoobarและมีเพียงไม่กี่ DIV ภายใน DIV ที่ไม่ได้จัดประเภทแต่ฉันคิดว่าพวกเขากำลังสืบทอดfoobarชั้นเรียน:

$('.foobar').on('click', function() { /*...do stuff...*/ });

ฉันต้องการให้มันดับลงเฉพาะเมื่อคลิกที่ไหนสักแห่งใน DIV แต่ไม่ใช่ในลูก DIV ของมัน

คำตอบ:


439

หากe.targetองค์ประกอบเดียวกันกับthisคุณไม่ได้คลิกที่ลูกหลาน

$('.foobar').on('click', function(e) {
  if (e.target !== this)
    return;
  
  alert( 'clicked the foobar' );
});
.foobar {
  padding: 20px; background: yellow;
}
span {
  background: blue; color: white; padding: 8px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class='foobar'> .foobar (alert) 
  <span>child (no alert)</span>
</div>


คำตอบนั้นอธิบายความคิดเห็นนี้
gdoron ให้การสนับสนุน Monica

@gdoron: อดัมใจดีเกินไป :)

1
สวัสดี @ vicky เพียงแค่ FYI JavaScript มีการเปรียบเทียบความเท่าเทียมกันของมูลค่าสองประเภท ===หรือ!==การนำมาใช้ประโยชน์"เข้มงวดเท่าเทียมกันเปรียบเทียบขั้นตอนวิธีการ"ในขณะที่==และ!=ใช้"ความเท่าเทียมกันบทคัดย่อเปรียบเทียบขั้นตอนวิธีการ"ซึ่งเป็นประเภทบีบบังคับ ภูมิปัญญาทั่วไปคือการมักจะใช้อย่างเข้มงวดเปรียบเทียบเว้นแต่มีความต้องการที่เฉพาะเจาะจงสำหรับประเภทบีบบังคับ(ตั้งแต่กฎที่มีความซับซ้อนน้อย) ในกรณีนี้เนื่องจากการเปรียบเทียบวัตถุมันไม่ได้สร้างความแตกต่าง แต่คุณจะพบว่าคนส่วนใหญ่ยังคงยึดติดกับการเปรียบเทียบที่เข้มงวด

1
@ vicky: ไม่เป็นไร มันยังคงถูกต้อง เพียงแค่ให้คุณ JS มีโอเปอเรเตอร์ที่ต่างกัน ;-)

3
นี่เป็นคำตอบที่ดีเพราะมันสามารถทำงานร่วมกับ Vanilla JS addEventListener และไม่เฉพาะเจาะจง jQuery
Michael Giovanni Pumo

64

ยังมีอีกวิธีหนึ่งที่ใช้งานได้หากคุณไม่สนใจเฉพาะการกำหนดเป้าหมายเบราว์เซอร์ใหม่ เพียงเพิ่ม CSS

pointer-events: none;

ถึงลูก ๆ ของ div ที่คุณต้องการจับภาพคลิก นี่คือตารางการสนับสนุน

http://caniuse.com/#feat=pointer-events


13
รู้ว่าฉันควรหลีกเลี่ยงการเขียนคำวิจารณ์ 'ขอบคุณ' แต่ฉันสามารถจูบคุณสำหรับสิ่งนี้ :-)
Simona Adriani

@SimonaAdriani เหรอ?
n3wb

ขอบคุณฉันทำแบบเดียวกัน แต่ฉันพยายามเขียนกรณีทดสอบหน่วยรอบ ๆ ฉันจะแน่ใจได้อย่างไรว่าclickควรปิดกั้นทริกเกอร์เหตุการณ์การคลิกโดยโปรแกรม
Pankaj Parkar

29

คุณสามารถใช้ฟองในความโปรดปรานของคุณ:

$('.foobar').on('click', function(e) {
    // do your thing.
}).on('click', 'div', function(e) {
    // clicked on descendant div
    e.stopPropagation();
});

นี่ดูเหมือนเป็นโซลูชันที่ดีสำหรับสถานการณ์เฉพาะของฉันเนื่องจากฉันเพียงต้องการยกเว้นการคลิกใน<a>องค์ประกอบที่สืบทอด มีเพียงปัญหาเดียวคือเมื่อฉันคลิกตรงกลางเหตุการณ์เหล่านั้นจะยังคงทริกเกอร์ (ทดสอบใน Google Chrome) มีอะไรที่แตกต่างกันที่ป้องกันสิ่งนี้หรือไม่?
cgogolin

@cgogolin ลองดูที่นี่: stackoverflow.com/questions/12197122/…
Jessica

28

ฉันไม่ได้รับคำตอบที่ยอมรับในการทำงาน แต่ดูเหมือนว่าจะทำเคล็ดลับอย่างน้อยใน Vanilla JS

if(e.target !== e.currentTarget) return;

1
e.currentTarget มีความแม่นยำมากกว่าการอ้างอิงthisเนื่องจากวัตถุที่thisชี้ไปสามารถเปลี่ยนแปลงได้ขึ้นอยู่กับขอบเขตและบริบทจากที่ที่มันถูกเรียกว่า
eballeste

20
//bind `click` event handler to the `.foobar` element(s) to do work,
//then find the children of all the `.foobar` element(s)
//and bind a `click` event handler to them that stops the propagation of the event
$('.foobar').on('click', function () { ... }).children().on('click', function (event) {
    event.stopPropagation();
    //you can also use `return false;` which is the same as `event.preventDefault()` and `event.stopPropagation()` all in one (in a jQuery event handler)
});

การดำเนินการนี้จะหยุดการเผยแพร่ (bubbling) ของclickกิจกรรมในองค์ประกอบย่อยของ.foobarองค์ประกอบใด ๆ ดังนั้นเหตุการณ์จะไม่ไปถึง.foobarองค์ประกอบที่จะยิงตัวจัดการเหตุการณ์

นี่คือตัวอย่าง: http://jsfiddle.net/bQQJP/



2

ฉันมีปัญหาเดียวกันและหาวิธีแก้ปัญหานี้ (ตามคำตอบอื่น ๆ )

 $( ".newsletter_background" ).click(function(e) {
    if (e.target == this) {
        $(".newsletter_background").hide();
    } 
});

โดยพื้นฐานแล้วจะบอกว่าถ้าเป้าหมายคือตัว div ให้ทำการรันโค้ดไม่เช่นนั้นจะไม่ทำอะไรเลย (อย่าซ่อน)


1

เคสของฉันคล้ายกัน แต่นี่เป็นโอกาสที่คุณจะมีจำนวนน้อยfoobarและคุณต้องการปิดเพียงอันเดียว - ต่อหนึ่งคลิก:

ค้นหากรณีหลัก

$(".foobar-close-button-class").on("click", function () {
    $(this).parents('.foobar').fadeOut( 100 );
    // 'this' - means that you finding some parent class from '.foobar-close-button-class'
    // '.parents' -means that you finding parent class with name '.foobar'
});

ค้นหากรณีเด็ก

$(".foobar-close-button-class").on("click", function () {
    $(this).child('.foobar-close-button-child-class').fadeOut( 100 );
    // 'this' - means that you finding some child class from '.foobar-close-button-class'
    // '.child' -means that you finding child class with name '.foobar-close-button-child-class'
});

1

คุณสามารถใช้ event.currentTarget มันจะทำคลิกเหตุการณ์เฉพาะผู้ที่ได้รับเหตุการณ์

target = e => {
    console.log(e.currentTarget);
  };
<ul onClick={target} className="folder">
      <li>
        <p>
          <i className="fas fa-folder" />
        </p>
      </li>
    </ul>


1

หากคุณไม่สามารถใช้งานpointer-events: none;และกำหนดเป้าหมายเป็นเบราว์เซอร์สมัยใหม่คุณสามารถใช้composedPathเพื่อตรวจจับการคลิกโดยตรงบนวัตถุดังนี้:

element.addEventListener("click", function (ev) {
    if (ev.composedPath()[0] === this) {
        // your code here ...
    }
})

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการแต่งเพลงประกอบได้ที่นี่: https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath


0

// if its li get value 
document.getElementById('li').addEventListener("click", function(e) {
                if (e.target == this) {
                    UodateNote(e.target.id);
                }
                })
                
                
                function UodateNote(e) {

    let nt_id = document.createElement("div");
    // append container to duc.
    document.body.appendChild(nt_id);
    nt_id.id = "hi";
    // get conatiner value . 
    nt_id.innerHTML = e;
    // body...
    console.log(e);

}
li{
 cursor: pointer;
    font-weight: bold;
  font-size: 20px;
    position: relative;
    width: 380px;
    height: 80px;
    background-color: silver;
    justify-content: center;
    align-items: center;
    text-align: center;
    margin-top: 0.5cm;
    border: 2px solid purple;
    border-radius: 12%;}
    
    p{
     cursor: text;
  font-size: 16px;
   font-weight: normal;
    display: block;
    max-width: 370px;
    max-height: 40px;
    overflow-x: hidden;}
<li id="li"><p>hi</p></li>

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