event - Implementación de la carpeta "en vivo" de jQuery con JavaScript nativo
jquery events w3schools (3)
Estoy tratando de averiguar cómo vincular un evento a elementos creados dinámicamente. Necesito que el evento persista en el elemento incluso después de que se destruya y se regenere.
Obviamente, con la función en vivo de jQuery es fácil, pero ¿qué aspecto tendrían implementado con Javascript nativo?
Además de la publicación de Andrew y el comentario de Binyamin, quizás esta sea una opción:
Con esto puedes usar ''nav .item a'' como selector. Basado en el código de Andrew.
function live (eventType, elementQuerySelector, cb) {
document.addEventListener(eventType, function (event) {
var qs = document.querySelectorAll(elementQuerySelector);
if (qs) {
var el = event.target, index = -1;
while (el && ((index = Array.prototype.indexOf.call(qs, el)) === -1)) {
el = el.parentElement;
}
if (index > -1) {
cb.call(el, event);
}
}
});
}
live(''click'', ''nav .aap a'', function(event) { console.log(event); alert(''clicked''); });
Aquí hay un ejemplo simple:
function live(eventType, elementId, cb) {
document.addEventListener(eventType, function (event) {
if (event.target.id === elementId) {
cb.call(event.target, event);
}
});
}
live("click", "test", function (event) {
alert(this.id);
});
La idea básica es que desea adjuntar un controlador de eventos al documento y dejar que el evento forme burbujas en el DOM. Luego, verifique la propiedad event.target
para ver si coincide con los criterios deseados (en este caso, solo que el id
del elemento).
Editar:
@shabunc descubrió un problema bastante grande con mi solución: los eventos en elementos secundarios no se detectarán correctamente. Una forma de solucionar esto es mirar los elementos de los antepasados para ver si alguno tiene el id
especificado:
function live (eventType, elementId, cb) {
document.addEventListener(eventType, function (event) {
var el = event.target
, found;
while (el && !(found = el.id === elementId)) {
el = el.parentElement;
}
if (found) {
cb.call(el, event);
}
});
}
Una alternativa a vincular dinámicamente un evento con un elemento específico podría ser un detector de eventos global. Por lo tanto, cada vez que actualice el DOM con otro nuevo elemento de evento en ese elemento también aparecerán las "capturas". Un ejemplo:
var mybuttonlist = document.getElementById(''mybuttonlist'');
mybuttonlist.addEventListener(''click'', e=>{
if(e.target.nodeName == ''BUTTON''){
switch(e.target.name){
case ''createnewbutton'':
mybuttonlist.innerHTML += ''<li><button name="createnewbutton">Create new button</button></li>'';
break;
}
}
}, false);
ul {
list-style: none;
padding: 0;
margin: 0;
}
<ul id="mybuttonlist">
<li><button name="createnewbutton">Create new button</button></li>
</ul>
En este ejemplo, tengo un detector de eventos en <ul>
para eventos de clic. Entonces, un evento sucede para todos los elementos secundarios. Desde el sencillo controlador de eventos que creé, puedes ver que es fácil agregar más lógica, más botones (con nombres diferentes o repetidos), anclas, etc.
Si lo desea, puede agregar el listador de eventos al documento en lugar del elemento de lista, capturando todos los eventos de clic en la página y luego controlar los eventos de clic en el controlador de eventos.