Bagaimana untuk memeriksa apakah secara dinamis terpasang event listener ada atau tidak?

Berikut ini adalah masalah saya: apakah mungkin entah bagaimana untuk memeriksa keberadaan dinamis yang terpasang acara pendengar? Atau bagaimana saya dapat memeriksa status "onclick" (?) properti di DOM? Saya telah mencari di internet seperti Stack Overflow untuk sebuah solusi, tetapi tidak berhasil. Di sini saya html:

<a id="link1" onclick="linkclick(event)"> link 1 </a>
<a id="link2"> link 2 </a> <!-- without inline onclick handler -->

Kemudian di Javascript saya lampirkan dibuat secara dinamis event listener untuk 2 link:

document.getElementById('link2').addEventListener('click', linkclick, false);

Kode berjalan dengan baik, tetapi semua upaya saya untuk mendeteksi yang terpasang pendengar yang gagal:

// test for #link2 - dynamically created eventlistener
alert(elem.onclick); // null
alert(elem.hasAttribute('onclick')); // false
alert(elem.click); // function click(){[native code]} // btw, what's this?

[jsFiddle di sini](https://jsfiddle.net/qv0k7Lor/). Jika anda klik "Tambahkan event onclick untuk 2" dan kemudian "[link 2]", peristiwa kebakaran baik, tapi "Test link 2" selalu laporan palsu. Ada yang bisa bantu?

Mengomentari pertanyaan (5)
Larutan

Tidak ada cara untuk memeriksa apakah secara dinamis terpasang acara pendengar ada atau tidak.

Satu-satunya cara anda dapat melihat jika pendengar acara terpasang adalah dengan melampirkan pendengar event seperti ini:

elem.onclick = function () { console.log (1) }

Anda kemudian dapat menguji apakah suatu peristiwa pendengar yang melekat pada onclick dengan kembali !!elem.onclick (atau sesuatu yang serupa).

Komentar (1)

Saya melakukan hal seperti itu:

const element = document.getElementById('div');

if (element.getAttribute('listener') !== 'true') {
     element.addEventListener('click', function (e) {
         const elementClicked = e.target;
         elementClicked.setAttribute('listener', 'true');
         console.log('event has been attached');
    });
}

Membuat atribut khusus untuk sebuah elemen ketika pendengar yang terpasang dan kemudian memeriksa jika ada.

Komentar (2)

Apa yang akan saya lakukan adalah membuat sebuah Boolean luar fungsi yang mulai keluar sebagai PALSU dan akan diatur untuk BENAR ketika anda melampirkan acara. Ini akan berfungsi sebagai semacam bendera untuk anda sebelum anda memasang acara lagi. Berikut ini's contoh ide.

// initial load
var attached = false;

// this will only execute code once
doSomething = function() {
  if (!attached) {
    attached = true;
    //code
  }
} 

//attach your function with change event
window.onload = function() {
    var txtbox = document.getElementById("textboxID");
    if(window.addEventListener){
        txtbox.addEventListener("change", doSomething, false);
    } else if(window.attachEvent){
        txtbox.attachEvent("onchange", doSomething);
    }
}
Komentar (1)

tl;dr: Tidak, anda tidak dapat melakukan hal ini dalam setiap native didukung jalan.


Satu-satunya cara yang saya tahu untuk mencapai hal ini akan membuat kustom bagasi objek di mana anda menyimpan catatan dari pendengar menambahkan. Sesuatu di sepanjang baris berikut:

/* Create a storage object. */
var CustomEventStorage = [];

Langkah 1: Pertama, anda akan membutuhkan sebuah fungsi yang dapat melintasi penyimpanan objek dan kembali catatan dari sebuah elemen diberi elemen (atau palsu).

/* The function that finds a record in the storage by a given element. */
function findRecordByElement (element) {
    /* Iterate over every entry in the storage object. */
    for (var index = 0, length = CustomEventStorage.length; index < length; index++) {
        /* Cache the record. */
        var record = CustomEventStorage[index];

        /* Check whether the given element exists. */
        if (element == record.element) {
            /* Return the record. */
            return record;
        }
    }

    /* Return false by default. */
    return false;
}

Langkah 2: Kemudian, anda akan membutuhkan sebuah fungsi yang dapat menambahkan event listener tapi juga menyisipkan pendengar untuk penyimpanan objek.

/* The function that adds an event listener, while storing it in the storage object. */
function insertListener (element, event, listener, options) {
    /* Use the element given to retrieve the record. */
    var record = findRecordByElement(element);

    /* Check whether any record was found. */
    if (record) {
        /* Normalise the event of the listeners object, in case it doesn't exist. */
        record.listeners[event] = record.listeners[event] || [];
    }
    else {
        /* Create an object to insert into the storage object. */
        record = {
            element: element,
            listeners: {}
        };

        /* Create an array for event in the record. */
        record.listeners[event] = [];

        /* Insert the record in the storage. */
        CustomEventStorage.push(record);
    }

    /* Insert the listener to the event array. */
    record.listeners[event].push(listener);

    /* Add the event listener to the element. */
    element.addEventListener(event, listener, options);
}

Langkah 3: sehubungan dengan kebutuhan yang sebenarnya dari pertanyaan anda, anda akan memerlukan berikut fungsi untuk memeriksa apakah suatu elemen telah menambahkan event listener untuk event tertentu.

/* The function that checks whether an event listener is set for a given event. */
function listenerExists (element, event, listener) {
    /* Use the element given to retrieve the record. */
    var record = findRecordByElement(element);

    /* Check whether a record was found & if an event array exists for the given event. */
    if (record && event in record.listeners) {
        /* Return whether the given listener exists. */
        return !!~record.listeners[event].indexOf(listener);
    }

    /* Return false by default. */
    return false;
}

Langkah 4: Akhirnya, anda akan membutuhkan sebuah fungsi yang dapat menghapus pendengar dari penyimpanan objek.

/* The function that removes a listener from a given element & its storage record. */
function removeListener (element, event, listener, options) {
    /* Use the element given to retrieve the record. */
    var record = findRecordByElement(element);

    /* Check whether any record was found and, if found, whether the event exists. */
    if (record && event in record.listeners) {
        /* Cache the index of the listener inside the event array. */
        var index = record.listeners[event].indexOf(listener);

        /* Check whether listener is not -1. */
        if (~index) {
            /* Delete the listener from the event array. */
            record.listeners[event].splice(index, 1);
        }

        /* Check whether the event array is empty or not. */
        if (!record.listeners[event].length) {
            /* Delete the event array. */
            delete record.listeners[event];
        }
    }

    /* Add the event listener to the element. */
    element.removeEventListener(event, listener, options);
}

Cuplikan:

window.onload = function () {
  var
    /* Cache the test element. */
    element = document.getElementById("test"),

    /* Create an event listener. */
    listener = function (e) {
      console.log(e.type + "triggered!");
    };

  /* Insert the listener to the element. */
  insertListener(element, "mouseover", listener);

  /* Log whether the listener exists. */
  console.log(listenerExists(element, "mouseover", listener));

  /* Remove the listener from the element. */
  removeListener(element, "mouseover", listener);

  /* Log whether the listener exists. */
  console.log(listenerExists(element, "mouseover", listener));
};

<script src = "https://cdn.rawgit.com/angelpolitis/custom-event-storage/master/main.js"></script>


<div id = "test" style = "background:#000; height:50px; width: 50px"></div>

Although lebih dari 5 tahun telah berlalu sejak OP memposting pertanyaan, saya percaya orang-orang yang tersandung itu di masa depan akan mendapatkan keuntungan dari jawaban ini, sehingga merasa bebas untuk membuat saran atau perbaikan untuk itu. 😊

Komentar (0)

Anda bisa mengeceknya secara manual jika anda EventListener ada yang menggunakan Chrome inspektur misalnya. Dalam Elemen tab yang anda miliki tradisional "Gaya" subtab dan dekat satu sama lain : "Pendengar Event". Yang akan memberikan anda daftar semua EventListeners dengan unsur-unsur terkait.

Komentar (0)

Mungkin duplikat: https://stackoverflow.com/questions/28056716/check-if-an-element-has-event-listener-on-it-no-jquery/41137585. Silakan temukan jawaban saya di sana.

Pada dasarnya di sini adalah trik untuk Kromium (Krom) browser:

getEventListeners(document.querySelector('your-element-selector'));
Komentar (0)

Berikut ini's sebuah script yang saya digunakan untuk memeriksa keberadaan dinamis yang terpasang acara pendengar. Saya menggunakan jQuery untuk memasang event handler untuk sebuah elemen, yang kemudian memicu peristiwa itu (dalam hal ini 'klik' event). Cara ini saya dapat mengambil dan menangkap acara sifat yang hanya akan ada jika event handler terpasang.

var eventHandlerType;

$('#contentDiv').on('click', clickEventHandler).triggerHandler('click');

function clickEventHandler(e) {
    eventHandlerType = e.type;
}

if (eventHandlerType === 'click') {
    console.log('EventHandler "click" has been applied');
}
Komentar (1)

Tampaknya aneh bahwa metode ini doesn't ada. Apakah sudah waktunya untuk menambahkan ini akhirnya?

Jika anda ingin anda bisa sesuatu seperti berikut (belum teruji):

var _addEventListener = EventTarget.prototype.addEventListener;
var _removeEventListener = EventTarget.prototype.removeEventListener;
EventTarget.prototype.events = {};
EventTarget.prototype.addEventListener = function(name, function, etc) {
   var events = EventTarget.prototype.events;
   if (events[name]==null) {
      events[name] = [];
   }

   if (events[name].indexOf(function)==-1) {
      events[name].push(function);
   }

   _addEventListener(name, function);
}
EventTarget.prototype.removeEventListener = function(name) {
   var events = EventTarget.prototype.events;

   if (events[name]!=null && events[name].indexOf(function)!=-1) {
      events[name].splice(events[name].indexOf(function), 1);
   }

   _removeEventListener(name, function);
}
EventTarget.prototype.hasEventListener = function(name) {
   var events = EventTarget.prototype.events;
   if (events[name]==null) {
      return false;
   }

   return events[name].length);
}
Komentar (0)

Hanya menghapus acara sebelum menambahkannya :

document.getElementById('link2').removeEventListener('click', linkclick, false);
document.getElementById('link2').addEventListener('click', linkclick, false);
Komentar (0)

Aku hanya menulis sebuah script yang memungkinkan anda mencapai hal ini. Ini memberi anda dua fungsi global: hasEvent(Node elm, String acara) dan getEvents(Node elm) yang dapat anda memanfaatkan. Diketahui bahwa ia memodifikasi EventTarget metode prototype add/RemoveEventListener, dan tidak bekerja untuk acara yang ditambahkan melalui markup HTML atau javascript sintaks elm.on_event = ...

Info lebih lanjut di GitHub

[Live Demo][2]

Script:

var hasEvent,getEvents;!function(){function b(a,b,c){c?a.dataset.events+=","+b:a.dataset.events=a.dataset.events.replace(new RegExp(b),"")}function c(a,c){var d=EventTarget.prototype[a+"EventListener"];return function(a,e,f,g,h){this.dataset.events||(this.dataset.events="");var i=hasEvent(this,a);return c&&i||!c&&!i?(h&&h(),!1):(d.call(this,a,e,f),b(this,a,c),g&&g(),!0)}}hasEvent=function(a,b){var c=a.dataset.events;return c?new RegExp(b).test(c):!1},getEvents=function(a){return a.dataset.events.replace(/(^,+)|(,+$)/g,"").split(",").filter(function(a){return""!==a})},EventTarget.prototype.addEventListener=c("add",!0),EventTarget.prototype.removeEventListener=c("remove",!1)}();
Komentar (0)

Ada doesn't muncul untuk menjadi browser lintas fungsi yang akan mencari acara yang terdaftar dalam suatu elemen.

Namun, adalah mungkin untuk melihat memanggil kembali fungsi untuk unsur-unsur di beberapa browser menggunakan alat-alat pengembangan. Hal ini dapat berguna ketika mencoba untuk menentukan bagaimana halaman web fungsi atau kode debugging.

Firefox

Pertama, melihat elemen dalam Inspektur tab dalam alat pengembang. Hal ini dapat dilakukan dengan:

  • Pada halaman dengan mengklik kanan pada item pada halaman web yang anda inginkan untuk memeriksa dan memilih "Inspect Element" dari menu.
  • Dalam console menggunakan fungsi untuk memilih elemen, seperti: dokumen.querySelector, dan kemudian mengklik ikon di samping elemen untuk melihat dalam Inspektur tab.

Jika ada peristiwa yang didaftarkan ke elemen, anda akan melihat tombol yang berisi kata Acara di samping elemen. Mengklik itu akan memungkinkan anda untuk melihat peristiwa-peristiwa yang telah terdaftar dengan elemen. Mengklik tanda panah di samping sebuah acara yang memungkinkan anda untuk melihat fungsi callback untuk itu.

Chrome

Pertama, melihat unsur Unsur tab dalam alat pengembang. Hal ini dapat dilakukan dengan:

  • Pada halaman dengan mengklik kanan pada item pada halaman web yang anda inginkan untuk memeriksa dan memilih "Memeriksa" dari menu
  • Dalam console menggunakan fungsi untuk memilih elemen, seperti: dokumen.querySelector, mengklik kanan elemen, dan memilih "Mengungkapkan dalam Elemen panel" untuk melihat dalam Inspektur tab.

Di bagian jendela yang menunjukkan pohon yang mengandung elemen-elemen halaman web, harus ada bagian lain dengan tab yang berjudul "Pendengar Event". Pilih untuk melihat peristiwa yang didaftarkan ke elemen. Untuk melihat kode untuk acara tertentu, klik link di sebelah kanan itu.

Di Chrome, acara untuk sebuah elemen juga dapat ditemukan dengan menggunakan getEventListeners fungsi. Namun, berdasarkan tes, getEventListeners fungsi doesn't daftar peristiwa ketika beberapa elemen yang melewati itu. Jika anda ingin menemukan semua elemen pada halaman yang memiliki pendengar dan melihat fungsi callback untuk orang-orang pendengar, anda dapat menggunakan kode berikut pada console untuk melakukan hal ini:


var elems = document.querySelectorAll('*');

for (var i=0; i 
Komentar (0)

Jika saya memahami dengan baik anda hanya dapat memeriksa jika pendengar telah diperiksa tetapi tidak yang pendengar adalah presenter khusus.

Sehingga beberapa ad hoc kode akan mengisi celah untuk menangani coding aliran. Metode praktis akan membuat sebuah negara menggunakan variabel. Misalnya, melampirkan pendengar's checker sebagai berikut:

var listenerPresent=false

maka jika anda menetapkan pendengar hanya mengubah nilai:

listenerPresent=true

kemudian dalam eventListener 's callback anda dapat menetapkan fungsi tertentu di dalam dan di dalam cara yang sama, mendistribusikan akses ke fungsi tergantung dari beberapa negara sebagai variabel misalnya:

accessFirstFunctionality=false
accessSecondFunctionality=true
accessThirdFunctionality=true
Komentar (0)

Anda bisa secara teori kuda-kudaan addEventListener dan removeEventListener untuk menambah memindahkan bendera ke 'ini' objek. Jelek dan saya belum't diuji ...

Komentar (0)

Aku hanya menemukan ini dengan mencoba untuk melihat apakah saya acara yang terpasang....

jika anda lakukan :

item.onclick

itu akan kembali "null"

tapi jika anda lakukan:

item.hasOwnProperty('onclick')

maka itu adalah "BENAR"

jadi saya berpikir bahwa ketika anda menggunakan "addEventListener" untuk menambahkan event handler, satu-satunya cara untuk mengaksesnya adalah melalui "hasOwnProperty". Aku berharap aku tahu mengapa atau bagaimana tapi sayangnya, setelah meneliti, saya belum't menemukan penjelasan.

Komentar (1)