Tıklama etkinliği SADECE ebeveyn DIV'de değil, çocuklarda nasıl tetiklenir?


211

Sınıflandırılmış bir DIV var foobarve bu DIV içinde sınıflandırılmamış birkaç DIV var, ama sanırım onlar foobarsınıfı miras :

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

Sadece DIV'de bir yere tıkladığınızda ateş etmesini istiyorum ama çocuklarının DIV'lerine değil.

Yanıtlar:


439

Eğer e.targetaynı unsurdur this, bir soydan tıklanmayan ettik.

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


Bu cevap bu yorumu açıklıyor
gdoron Monica'yı destekliyor

@gdoron: Adam çok kibar davranıyor. :)

1
Merhaba @vicky. Sadece FYI, JavaScript'in iki farklı değer eşitliği karşılaştırması vardır. ===Veya !==kullanımları "Sıkı Eşitlik Karşılaştırma Algoritması" iken ==ve !=kullanımları "Özet Eşitlik Karşılaştırma Algoritma" tipi zorlayıcı olduğunu. Genel bilgelik, zorlayıcı tipe özel bir ihtiyaç olmadığı sürece her zaman sıkı bir karşılaştırma yapmaktır (çünkü kuralları biraz karmaşıktır) . Bu durumda, nesneler karşılaştırıldığından, gerçekten bir fark yaratmaz, ancak çoğu insanın sıkı karşılaştırmaya sadık kalacağını göreceksiniz .

1
@vicky: Sorun değil. Hala doğru. Sadece JS'nin farklı operatörlere sahip olmasına izin vermek. ;-)

3
Vanilla JS addEventListener ile de çalışabileceği ve jQuery'ye özgü olmadığı için bu iyi bir cevaptır.
Michael Giovanni Pumo

64

Yalnızca daha yeni tarayıcıları hedeflememeniz durumunda çalışan başka bir yol daha vardır. Sadece CSS'yi ekleyin

pointer-events: none;

div'in herhangi bir çocuğuna tıklamayı yakalamak istersiniz. İşte destek tabloları

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


13
'Teşekkürler' yorumları yazmaktan kaçınmam gerektiğini biliyorum, ama bunun için seni öpebilirim :-)
Simona Adriani

@SimonaAdriani ha?
n3wb

Teşekkürler, ben de aynı şekilde yaptım, ama etrafına birim test senaryosu yazmak için uğraşıyorum. clickProgramlı tıklama etkinliği tetikleyicisinin engellenmesini nasıl sağlayabilirim ?
Pankaj Parkar

29

Köpürmeyi kendi lehinize kullanabilirsiniz:

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

Bu yalnızca özel senaryom için güzel bir çözüm gibi görünüyor, çünkü yalnızca alt <a>öğelere yapılan tıklamaları hariç tutmak istiyorum . Tek bir sorun var: Onlara orta tıkladığımda etkinlik hala tetikleniyor (Google Chrome'da test edildi). Bunu da engelleyen bir varyantı var mı?
cgogolin

@cgogolin, şuna bir göz atın: stackoverflow.com/questions/12197122/…
Jessica

28

İşe kabul edilen cevabı alamadım, ama bu en azından vanilya JS'de hile yapıyor gibi görünüyor.

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

1
e.currentTarget referans göstermekten daha doğrudur thisçünkü thisişaret eden nesne , arandığı kapsam ve bağlama göre değişebilir
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)
});

Bu, clickolayın unsur (lar) ın alt öğelerinden herhangi birinde yayılmasını (köpürmesini) durduracak, .foobarböylece olay, .foobarolay işleyicilerini çalıştırmak için öğelere ulaşmayacaktır .

İşte bir demo: http://jsfiddle.net/bQQJP/


3
$(".advanced ul li").live('click',function(e){
    if(e.target != this) return;
    //code
    // this code will execute only when you click to li and not to a child
})

2

Aynı sorunu yaşadım ve bu çözümü buldum (diğer cevaplara dayanarak)

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

Temel olarak, hedef div ise kodu çalıştırır, aksi takdirde hiçbir şey yapmaz (gizlemeyin)


1

Benim durumum benzer, ancak birkaç tane olduğunda foobarve yalnızca bir tıklamada bir tıklatmak istediğinizde bu durum söz konusudur :

Ana vakayı bul

$(".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'
});

Alt vakayı bul

$(".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 kullanabilirsiniz. Sadece etkinlik olan tıklama etkinliğini yapar.

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;Modern tarayıcıları kullanamıyorsanız ve hedefliyorsanız composedPath, nesneye doğrudan bir tıklamayı algılamak için kullanabilirsiniz :

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

CombinedPath hakkında daha fazla bilgiyi buradan edinebilirsiniz: 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>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.