Come verificare se il listener di eventi collegato dynamicmente esiste o no?

Ecco il mio problema: è ansible in qualche modo verificare l’esistenza di listener di eventi collegati dynamicmente? O come posso controllare lo stato della proprietà “onclick” (?) In DOM? Ho cercato internet proprio come StackOverflow per una soluzione, ma senza fortuna. Ecco il mio html:

 link 1   link 2   

Quindi in javascript allego il listener di eventi creato dynamicmente al 2 ° link:

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

Il codice funziona bene, ma tutti i miei tentativi di rilevare quel listener collegato falliscono:

 // 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 è qui . Se si fa clic su “Aggiungi onclick per 2” e quindi su “[collegamento 2]”, l’evento si triggers correttamente, ma il “Collegamento test 2” riporta sempre falso. Qualcuno può aiutare?

Non c’è modo di verificare se esistono listener di eventi collegati dynamicmente o meno.

L’unico modo per vedere se un listener di eventi è collegato è allegando listener di eventi come questo:

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

Puoi quindi verificare se un ascoltatore di eventi è stato collegato a onclick restituendo !!elem.onclick (o qualcosa di simile).

Quello che vorrei fare è creare un booleano al di fuori della tua funzione che inizi come FALSE e si imposti su VERO quando alleghi l’evento. Questo dovrebbe servire come una sorta di bandiera per te prima di albind nuovamente l’evento. Ecco un esempio dell’idea.

 // 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); } } 

Puoi sempre controllare manualmente se il tuo EventListener esiste utilizzando la finestra di ispezione di Chrome, ad esempio. Nella scheda Elemento hai la sottotabella “Stili” tradizionale e vicino ad essa un’altra: “Listener di eventi”. Quale ti darà la lista di tutti gli EventListeners con i loro elementi collegati.

Ho fatto qualcosa del genere:

 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'); }); } 

Creazione di un attributo speciale per un elemento quando il listener è collegato e quindi verifica se esiste.

tl; dr : No, non puoi farlo in alcun modo supportato a livello nativo.


L’unico modo che conosco per ottenere questo sarebbe creare un object di archiviazione personalizzato dove si tiene una registrazione degli ascoltatori aggiunti. Qualcosa seguendo le linee seguenti:

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

Passo 1: In primo luogo, avrete bisogno di una funzione che possa attraversare l’object di archiviazione e restituire il record di un elemento dato l’elemento (o falso).

 /* 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; } 

Passo 2: Quindi, avrai bisogno di una funzione che possa aggiungere un listener di eventi ma anche di inserire il listener nell'object di archiviazione.

 /* 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); } 

Passaggio 3: per quanto riguarda il requisito effettivo della domanda, è necessario la seguente funzione per verificare se un elemento è stato aggiunto un listener di eventi per un evento specificato.

 /* 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; } 

Passaggio 4: Infine, sarà necessaria una funzione che possa eliminare un listener dall'object di archiviazione.

 /* 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); } 

Frammento:

 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)); }; 
    

Ecco uno script che ho usato per verificare l’esistenza di un listener di eventi collegato dynamicmente. Ho usato jQuery per colbind un gestore di eventi a un elemento, quindi triggersre quell’evento (in questo caso l’evento “clic”). In questo modo posso recuperare e acquisire proprietà di eventi che esisteranno solo se il gestore di eventi è collegato.

 var eventHandlerType; $('#contentDiv').on('click', clickEventHandler).triggerHandler('click'); function clickEventHandler(e) { eventHandlerType = e.type; } if (eventHandlerType === 'click') { console.log('EventHandler "click" has been applied'); } 

Possibile duplicato: controlla se un elemento ha un listener di eventi su di esso. nessun jquery . Per favore trova la mia risposta lì.

Fondamentalmente ecco il trucco per il browser Chromium (Chrome):

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

Ho appena scritto una sceneggiatura che ti permette di ottenere questo. Ti offre due funzioni globali: hasEvent(Node elm, String event) e getEvents(Node elm) che puoi utilizzare. Si noti che modifica il metodo prototipo EventTarget add/RemoveEventListener e non funziona per gli eventi aggiunti tramite il markup HTML o la syntax javascript di elm.on_event = ...

Maggiori informazioni su GitHub

Dimostrazione dal vivo

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)}(); 

L’ho appena scoperto cercando di vedere se il mio evento fosse allegato ….

se fate :

 item.onclick 

restituirà “null”

ma se lo fai:

 item.hasOwnProperty('onclick') 

allora è “VERO”

quindi penso che quando si utilizza “addEventListener” per aggiungere gestori di eventi, l’unico modo per accedervi è attraverso “hasOwnProperty”. Vorrei sapere perché o come, ma ahimè, dopo aver fatto ricerche, non ho trovato una spiegazione.

In teoria si potrebbe aggiungere addEventListener e removeEventListener per aggiungere rimuovere un flag all’object “this”. Brutto e non ho provato …