Sınıfta JavaScript tıklama etkinliği dinleyicisi


220

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

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

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

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

Bana özniteliği anlatmak için sınıflardan birine her tıkladığımda bir uyarı kutusu almayı bekliyordum ama maalesef bu işe yaramıyor. Birisi yardım edebilir mi lütfen?

( Not - Ben oldukça kolay yapabilirsiniz jQueryama olur DEĞİL kullanmak gibi )


2
Olay dinleyicisini ekleyen kodla ilgili bir sorun var. addEventListener olay adını ('klik'), işleve referansı (şimdi parf ile myFunction () öğesini çağırarak işlevin sonucunu değil) ve olay köpürmeyi gösteren bir bayrağı alır. AddEventListener çağrısı şöyle görünmelidir: elem.addEventListener ('click', myFunction, false) ve sınıf adı bir NodeList türüdür. Tüm öğelerin üzerinden geçmeli ve dinleyiciyi listedeki her birine eklemeniz gerekir.
Joey Guerra

Yanıtlar:


373

Bu çalışmalı. ölçütlerle eşleşen öğelerin getElementsByClassNamebir dizi Dizi benzeri nesnesi (düzenlemeye bakın) döndürür .

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

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

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

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

Eğer varsa ES6 destekleyen sizinle Son sözünü değiştirebilirsiniz:

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

Not: Eski tarayıcılar (IE6, IE7, IE8 gibi) desteklemez getElementsByClassNameve bu nedenle geri döner undefined.


DÜZENLEME: Düzeltme

getElementsByClassNamebir dizi döndürmez, ancak çoğunda HTMLCollection veya bazı tarayıcılarda NodeList ( Mozilla ref ) döndürür . Bu türlerin her ikisi de Dizi benzeri'dir (bir length özelliğine sahip oldukları ve nesnelere dizinleri aracılığıyla erişilebileceği anlamına gelir), ancak kesinlikle bir Dizi değildir veya bir Diziden miras alınır. (yani bir Dizi üzerinde gerçekleştirilebilecek diğer yöntemler bu türler üzerinde gerçekleştirilemez)

@ Nemo kullanıcısına bunu işaret ettiği ve tam olarak anlayabilmem için teşekkürler .


6
Bu mükemmel çalışıyor. Teşekkür ederim. Aslında jQuery döngü yaptı farkında değildi. Büyük yardım Anudeep. İşte çalışma cevabınız: jsfiddle.net/LWda3/2
30secondstosam

2
document.getElementsByClassNameölçütlerle eşleşse bile aslında her zaman bir dizi döndürür
Guilherme Sehn

Dizinin ilk öğesi tüm dom öğeleri olmasına rağmen dikkatli olun. Yani döngü için 1 ile başlayın
Vishal Sakaria

11
stackoverflow.com/a/13258908/1333493 "document.getElementsByClassName bir dizi döndürmüyor. XML dosyası gibi gezinen bir düğüm listesi döndürüyor."
Nemo

9
Array.from()harita fonksiyonu olan ikinci bir parametreye sahiptir, böylece yukarıdakiler (es6 desteği varsayarak) yazılabilir Array.from(classname, c => c.addEventListener('click', myFunction));.
17'de Kilmazing

12

* Bu, hedef sınıftaki çocukların olayları tetiklemesine izin vermek için düzenlendi. Ayrıntılar için cevabın alt kısmına bakınız. *

Öğelerin sık sık eklendiği ve kaldırıldığı bir sınıfa olay dinleyicisi eklemek için alternatif bir yanıt. Bu onolay, olayın dinlediği bir alt öğe için seçiciyi iletebileceğiniz jQuery işlevinden esinlenmiştir .

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öğenin alt öğelerine yapılan tıklamaları dinler ve bir tıklamanın hedefinde seçiciyle eşleşen bir üst öğe varsa, sınıf etkinliği işlenir. Tek tek öğelere daha fazla tıklama dinleyicisi eklemek zorunda kalmadan öğeleri istediğiniz gibi ekleyebilir ve kaldırabilirsiniz. Bu, bu dinleyici eklendikten sonra eklenen öğeler için bile, jQuery işlevselliği gibi (kaputun altında biraz benzer olduğunu düşünüyorum) hepsini yakalayacaktır.

Bu, ilerleyen olaylara bağlıdır, bu nedenle stopPropagationbaşka bir yerde etkinlik yapıyorsanız , bu çalışmayabilir. Ayrıca, closestişlevin görünüşte IE ile bazı uyumluluk sorunları var (ne değil?).

Bu tür bir eylemi tekrar tekrar dinlemeniz gerekiyorsa, bu bir işlev haline getirilebilir.

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 yayın ilk kullanılan matchesiçin işlevini Etkinlik hedefindeki DOM öğeleri, ancak bu, etkinliklerin hedeflerini yalnızca doğrudan sınıfla sınırlandırdı. Bunun closestyerine, işlevi kullanmak üzere güncellendi ve istenen sınıftaki çocuklar üzerindeki olayların da olayları tetiklemesine izin verildi. Orijinal matcheskod orijinal kemanda bulunabilir: https://jsfiddle.net/u6oje7af/23/


3

Aşağıdaki kodu kullanabilirsiniz:

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

Bunu denemeliyim, bakımı ve döngüden daha iyi performans göstermesi daha kolay olabilecek benzersiz bir yaklaşım!
Cliff Helsel

4
öğenin birden fazla sınıfı varsa, bu alanlarda doğru değeri kontrol etmeniz gerekir. sınıflar ve düzen. tercih ederimevt.target.classList.contains('databox')
honk31

8
Bu bana çok verimsiz geliyor. Vücuttaki her olay bu işlevden geçer. Bir döngü hakkında bakımı ne kadar zor?
JosefAssad

Bu çok verimsizdir, @JosefAssad'ın dediği gibi her öğeden geçersiniz.
nullwriter

3

Modern JavaScript ile şu şekilde yapılabilir:

const divs = document.querySelectorAll('.a');

divs.forEach(el => el.addEventListener('click', event => {
  console.log(event.target.classList[1]);
}));
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Example</title>
  <style>
    .a {
      background-color:red;
      height: 33px;
      display: flex;
      align-items: center;
      margin-bottom: 10px;
      cursor: pointer;
    }
    
    .b {
      background-color:#00AA00;
      height: 50px;
      display: flex;
      align-items: center;
      margin-bottom: 10px;
    }
  </style>
</head>
<body>
  <div class="a a-1">1</div>
  <div class="b">2</div>
  <div class="a a-2">11</div>
</body>
</html>

  1. Tüm öğeleri sınıf adına göre alır
  2. ForEach kullanarak tüm öğelerin üzerinde döngüler
  3. Her öğeye bir olay dinleyicisi ekleyin
  4. Kullanımları event.targetbelli bir elemanın daha fazla bilgi almak için
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.