tiene saber que pasar lista hizo eventos evento elemento ejemplos detectar delegacion javascript testing javascript-events addeventlistener

javascript - saber - ¿Cómo verificar si existe o no un detector de eventos conectado dinámicamente?



saber en que elemento se hizo click jquery (10)

Aquí está mi problema: ¿es posible verificar de algún modo la existencia de un detector de eventos conectado dinámicamente? ¿O cómo puedo verificar el estado de la propiedad "onclick" (?) En DOM? Busqué una solución en Internet como StackOverflow, pero no tuve suerte. Aquí está mi html:

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

Luego, en javascript, adjunto el detector de eventos creado dinámicamente al segundo enlace:

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

El código funciona bien, pero todos mis intentos de detectar ese oyente adjunto fallan:

// 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 está aquí . Si hace clic en "Agregar al hacer clic para 2" y luego "[enlace 2]", el evento se dispara bien, pero el "Enlace de prueba 2" siempre informa de que es falso. ¿Alguien puede ayudar?


Acabo de escribir un guión que te permite lograr esto. Le da dos funciones globales: hasEvent(Node elm, String event) y getEvents(Node elm) que puede utilizar. Tenga en cuenta que modifica el método prototipo EventTarget add/RemoveEventListener , y no funciona para los eventos agregados a través de marcado HTML o la sintaxis javascript de elm.on_event = ...

Más información en GitHub

Demo en vivo

Guión:

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


Aquí hay un script que usé para verificar la existencia de un detector de eventos conectado dinámicamente. Usé jQuery para adjuntar un controlador de eventos a un elemento, luego desencadené ese evento (en este caso, el evento ''clic''). De esta forma puedo recuperar y capturar propiedades de eventos que solo existirán si se adjunta el controlador de eventos.

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


En teoría, podría utilizar addEventListener y removeEventListener para agregar eliminar una marca al objeto ''this''. Feo y no he probado ...


Hice algo así:

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

Crea un atributo especial para un elemento cuando el detector está conectado y luego verifica si existe.


Lo que haría sería crear un booleano fuera de su función que comience como FALSE y se establezca en TRUE cuando adjunte el evento. Esto te serviría como una especie de bandera antes de volver a unir el evento. Aquí hay un ejemplo de la 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); } }


Me acabo de enterar tratando de ver si mi evento estaba conectado ...

si lo haces :

item.onclick

devolverá "nulo"

pero si lo haces:

item.hasOwnProperty(''onclick'')

entonces es "VERDADERO"

así que creo que cuando usas "addEventListener" para agregar manejadores de eventos, la única manera de acceder a ellos es a través de "hasOwnProperty". Desearía saber por qué o cómo, pero desafortunadamente, después de investigar, no encontré una explicación.


No hay forma de comprobar si existen escuchas de eventos adjuntos dinámicamente o no.

La única forma en que puede ver si un detector de eventos está conectado es adjuntando detectores de eventos como este:

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

Luego puede probar si un detector de eventos se adjuntó a onclick al devolver !!elem.onclick (o algo similar).



Siempre puede verificar manualmente si su EventListener existe usando el inspector de Chrome, por ejemplo. En la pestaña Elemento, tiene la subficha "Estilos" tradicional y cerca de ella, otra: "Escuchas de eventos". Lo cual le dará la lista de todos los EventListeners con sus elementos vinculados.


tl; dr : No, no puedes hacer esto de forma nativa.

La única manera que conozco para lograr esto sería crear un objeto de almacenamiento personalizado donde guarde un registro de los oyentes agregados. Algo a lo largo de las siguientes líneas:

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

Paso 1: Primero, necesitará una función que pueda atravesar el objeto de almacenamiento y devolver el registro de un elemento dado el 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; }

Paso 2: Entonces, necesitará una función que pueda agregar un detector de eventos pero también insertar el oyente en el objeto de almacenamiento.

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

Paso 3: Con respecto al requisito real de su pregunta, necesitará la siguiente función para verificar si un elemento ha sido agregado a un detector de eventos para un evento específico.

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

Paso 4: Finalmente, necesitará una función que pueda eliminar un oyente del objeto de almacenamiento.

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

Retazo:

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

<!-- Include the Custom Event Storage file --> <script src = "https://cdn.rawgit.com/angelpolitis/custom-event-storage/master/main.js"></script> <!-- A Test HTML element --> <div id = "test" style = "background:#000; height:50px; width: 50px"></div>

Aunque pasaron más de 5 años desde que OP publicó la pregunta, creo que las personas que se topen con ella en el futuro se beneficiarán de esta respuesta, así que siéntase libre de hacerle sugerencias o mejoras. 😊