Soru Bir çocuk ankrajı tıklandığında ebeveynin onclick etkinliğinin nasıl ateşlenmesini nasıl önleyebilirim?


Şu anda bir div tıklanabilir yapmak için jQuery kullanıyorum ve bu div de çapa var. İçinde bulunduğum sorun şu ki bir bağlantıyı tıkladığımda hem tıklama olayları hem de (div ve çapa için) ateş ediyor. Bir anchor tıklandığında div onclick olayının nasıl ateşlenmesini nasıl engellerim?

İşte bozuk kod:

JavaScript

var url = $("#clickable a").attr("href");

$("#clickable").click(function() {
    window.location = url;
    return true;
})

HTML

<div id="clickable">
    <!-- Other content. -->
    <a href="http://foo.com">I don't want #clickable to handle this click event.</a>
</div>

254
2017-09-02 17:19


Menşei




Cevaplar:


Etkinlikler, bir tıklama etkinliğinin eklendiği DOM'deki en yüksek noktaya kabarcıklar. Bu nedenle, örneğinizde, div'da açıkça başka herhangi bir tıklanabilir öğe olmasa bile, div'in her alt öğesi, tıklama etkinliğini işleyici tarafından yakalanıncaya kadar tıklama olaylarını DOM'a taşır.

Bunun için iki çözüm var, olayın gerçekte kim olduğunu görmek için kontrol etmektir. jQuery, olayla birlikte bir eventargs nesnesini geçirir:

$("#clickable").click(function(e) {
    var senderElement = e.target;
    // check if sender is the DIV element e.g.
    // if($(e.target).is("div")) {
    window.location = url;
    return true;
});

Ayrıca bağlantılarınıza bir tıklama olayı işleyicisi de ekleyebilirsiniz. olay köpürmeyi durdur kendi işleyicisinin çalıştırılmasından sonra:

$("#clickable a").click(function(e) {
   //do something
   e.stopPropagation();
})

348
2017-09-02 17:26



Mükemmel cevap. Orada da seçenekler olduğunu bilmek güzel. - Jonathon Watney
1! StopPropagation ile bir tıklama işleyici eklemek çok güzel bir hiledir, teşekkürler! - Thomas
Eğer yayılımı önlemek istediğiniz bir dizi öğeniz varsa, ana öğelerini bulabilir ve kafa onu oradan kabarcıklaşmasını engelleyebilir. Yani, bir divdaki tüm bağlantıları engellemekten ziyade, örneğin, sadece tıklamayı, div'un kendisinde bile durdurun ve daha yüksek bir seviyeye gitmesini engelleyin. - sucitivel
Çok teşekkür ederim. Bu son zamanlarda karşılaştım ve bu gerçekten bana yardımcı oldu. Bu js fiddle bir örnektir. jsfiddle.net/FgwQz - Butter Beer
kullanma if( e.target !== this) return; ebeveynte daha iyidir e.stopPropagation() Çocuğun çocuklarına bazı işleyicileri ekleyip eklemediğini ya da bir kütüphanenin bir çocuğa bir işleyiciyi eklemesi gerekmediğini (ve kütüphane koduyla uğraşmak istemediğinizi) bilmediğinizden beri. Bu endişelerin daha iyi bir ayrımı. - UTF_or_Death


kullanım stopPropagation yöntem, bir örneğe bakın:

$("#clickable a").click(function(e) {
   e.stopPropagation();
});

JQuery Dokümanlar tarafından söylendiği gibi:

stopPropagation yöntem, etkinliğin DOM'ı doldurmasını engeller   ağaç, herhangi bir ana işleyicinin olaya bildirilmesini önler.

Bunun olmadığını unutmayın. başkalarının dinleyicilerini bu olayla ilgilenmesini engellemek(örn. bir düğme için birden fazla tıklama işleyicisi), istenen etki değilse, kullanmanız gerekir stopImmediatePropagation yerine.


84
2017-09-02 17:24



+1 bu aradığım mükemmel cevaptı. - James


Burada benim jQuery olmayan bir kod (saf javascript) arıyor herkes için benim çözüm

document.getElementById("clickable").addEventListener("click", function( e ){
    e = window.event || e; 
    if(this === e.target) {
        // put your code here
    }
});

Ebeveyninizin oğullarına tıklandığında kodunuz çalıştırılamaz


34
2018-04-07 18:53



Bu benim için çalıştı, JS / jQuery olmayan bir çözüme ihtiyacım vardı. 10x! - L A
Teşekkürler, saatlerimi kurtardın - sanjeev shetty


bunu da deneyebilirsiniz

$("#clickable").click(function(event) {
   var senderElementName = event.target.tagName.toLowerCase();
   if(senderElementName === 'div')
   {
       // do something here 
   } 
   else
   {
      //do something with <a> tag
   }
});

10
2017-08-16 10:50



iyi numara! Bu benim zamanımı kurtardı! teşekkür ederim - peiman F.


kullanma return false; veya e.stopPropogation(); daha fazla kodun yürütülmesine izin vermez. Bu noktada akışını durduracak.


8
2018-04-15 15:27



Evet, bu önemli - bu kendime koştum. Ancak, Rex'ten gelen cevap yararlıdır - tıklanan öğeyi alabilir ve bazı durumlarda bunu durdurmaya çalıştığınız mantıkta kullanabilirsiniz. .target.nodeName ayrıca nelerin vurulduğuna dair net bir fikir edinmeye yardımcı oldu. - Watercayman


Tıklanabilir div'da birden çok öğeniz varsa, bunu yapmalısınız:

$('#clickable *').click(function(e){ e.stopPropagation(); });

7
2017-08-11 10:15





Herhangi bir durumda iç elemanlar ile etkileşime girmeyi düşünmüyorsanız, bir CSS çözümü sizin için yararlı olabilir.

Sadece iç elemanı / değerleri pointer-events: none

Senin durumunda:

.clickable > a {
    pointer-events: none;
}

veya tüm iç öğeleri genel olarak hedeflemek:

.clickable * {
    pointer-events: none;
}

ReactJS ile geliştirirken bu kolay kesmek bana çok zaman kazandırdı

Tarayıcı desteği şu adreste bulunabilir: http://caniuse.com/#feat=pointer-events


6
2018-05-04 09:07