Sınıf üzerinde JavaScript tıklama olayı dinleyicisi

Şu anda tıklanan sınıfın niteliğini almak için bazı JavaScript'ler yazmaya çalışıyorum. Bunu doğru şekilde yapmak için bir olay dinleyicisi kullanmam gerektiğini biliyorum. Kodum aşağıdaki gibi:

var classname = document.getElementsByClassName("classname");

var myFunction = function() {
    var attribute = this.getAttribute("data-myattribute");
    alert(attribute);
};

classname.addEventListener('click', myFunction(), false);

Sınıflardan birine her tıkladığımda bana niteliği bildiren bir uyarı kutusu almayı bekliyordum ama maalesef bu işe yaramıyor. Biri yardım edebilir mi lütfen?

(Not - Bunu jQuery ile kolayca yapabilirim ancak KULLANMAK İSTEMEM)

Çözüm

Bu işe yaramalı. getElementsByClassName`, ölçütlerle eşleşen öğelerden oluşan bir array Array benzeri nesne (düzenlemeye bakın) döndürür.

var classname = document.getElementsByClassName("classname");

var myFunction = function() {
    var attribute = this.getAttribute("data-myattribute");
    alert(attribute);
};

for (var i = 0; i < classname.length; i++) {
    classname[i].addEventListener('click', myFunction, false);
}

jQuery, düz JavaScript'te yapmanız gereken döngü kısmını sizin için yapar.

Eğer ES6 desteğiniz varsa son satırınızı şu şekilde değiştirebilirsiniz:

    Array.from(classname).forEach(function(element) {
      element.addEventListener('click', myFunction);
    });

Not: Eski tarayıcılar (IE6, IE7, IE8 gibi) getElementsByClassName'i desteklemez ve bu nedenleundefined' döndürürler.


EDIT : Düzeltme

getElementsByClassName bir dizi döndürmez, ancak çoğu tarayıcıda bir HTMLCollection veya bazı tarayıcılarda bir NodeList döndürür (Mozilla ref). Bu türlerin her ikisi de Dizi Benzeri'dir (yani bir uzunluk özelliğine sahiptirler ve nesnelere indeksleri aracılığıyla erişilebilir), ancak kesinlikle bir Dizi değildir veya bir Diziden miras alınmamıştır. (yani bir Array üzerinde gerçekleştirilebilen diğer yöntemler bu türler üzerinde gerçekleştirilemez)

Bunu belirttiği ve tam olarak anlamamı sağladığı için @Nemo kullanıcısına teşekkürler.

Yorumlar (11)

Bu, hedef sınıfın çocuklarının olayları tetiklemesine izin verecek şekilde düzenlendi. Ayrıntılar için yanıtın altına bakın.

Öğelerin sık sık eklendiği ve çıkarıldığı bir sınıfa olay dinleyicisi eklemek için alternatif bir yanıt. Bu, jQuery'nin on fonksiyonundan esinlenilmiştir; burada olayın dinlediği bir alt öğe için bir seçici iletebilirsiniz.

var base = document.querySelector('#base'); // the container for the variable content
var selector = '.card'; // any css selector for children

base.addEventListener('click', function(event) {
  // find the closest parent of the event target that
  // matches the selector
  var closest = event.target.closest(selector);
  if (closest && base.contains(closest)) {
    // handle class event
  }
});

Keman: https://jsfiddle.net/u6oje7af/94/

Bu, base öğesinin çocuklarına yapılan tıklamaları dinleyecek ve bir tıklamanın hedefinin seçiciyle eşleşen bir ebeveyni varsa, sınıf olayı işlenecektir. Tek tek öğelere daha fazla tıklama dinleyicisi eklemek zorunda kalmadan istediğiniz gibi öğe ekleyebilir ve kaldırabilirsiniz. Bu dinleyici eklendikten sonra eklenen öğeler için bile hepsini yakalayacaktır, tıpkı jQuery işlevselliği gibi (kaputun altında biraz benzer olduğunu hayal ediyorum).

Bu, olayların yayılmasına bağlıdır, bu nedenle olay üzerinde başka bir yerde stopPropagation yaparsanız, bu çalışmayabilir. Ayrıca, closest fonksiyonunun görünüşe göre IE ile bazı uyumluluk sorunları var (ne yok ki?).

Bu tür bir dinleme eylemini tekrar tekrar yapmanız gerekiyorsa, bu bir işlev haline getirilebilir, örneğin

function addChildEventListener(base, eventName, selector, handler) {
  base.addEventListener(eventName, function(event) {
    var closest = event.target.closest(selector);
    if (closest && base.contains(closest)) {
      // passes the event to the handler and sets `this`
      // in the handler as the closest parent matching the
      // selector from the target element of the event
      handler.call(closest, event);
    }
  });
}

========================================= DÜZENLEME: Bu yazı başlangıçta olay hedefindeki DOM öğeleri için matches işlevini kullanıyordu, ancak bu, olayların hedeflerini yalnızca doğrudan sınıfla sınırlıyordu. Bunun yerine closest fonksiyonunu kullanmak için güncellendi ve istenen sınıfın çocukları üzerindeki olayların da olayları tetiklemesine izin verildi. Orijinal matches kodu orijinal fiddle'da bulunabilir: https://jsfiddle.net/u6oje7af/23/

Yorumlar (0)

Aşağıdaki kodu kullanabilirsiniz:

document.body.addEventListener('click', function (evt) {
    if (evt.target.className === 'databox') {
        alert(this)
    }
}, false);
Yorumlar (4)