javascript dom publish-subscribe event-delegation

javascript - Delegación de eventos Vanilla JS: tratar con elementos secundarios del elemento de destino



dom publish-subscribe (2)

Nuevos navegadores

Los navegadores más nuevos admiten .matches :

this.container.addEventListener(''click'', function(e){ if (e.target.matches(''#game-again,#game-again *'')) { e.stopPropagation(); self.publish(''primo:evento''); } });

Puede obtener la versión sin prefijo con

var matches = document.body.matchesSelector || document.body.webkitMatchesSelector || document.body.mozMatchesSelector || document.body.msMatchesSelector || document.body.webkitMatchesSelector

Y luego use .apply para más navegadores (Still IE9 +).

Navegadores antiguos

Suponiendo que tenga que admitir navegadores más antiguos, puede subir el DOM:

function hasInParents(el,id){ if(el.id === id) return true; // the element if(el.parentNode) return hasInParents(el.parentNode,id); // a parent return false; // not the element nor its parents }

Sin embargo, esto escalará todo el dom, y desea detenerse en el objetivo de la delegación:

function hasInParentsUntil(el,id,limit){ if(el.id === id) return true; // the element if(el === limit) return false; if(element.parentNode) return hasInParents(el.parentNode,id); // a parent return false; // not the element nor its parents }

Lo cual, haría su código:

this.container.addEventListener(''click'', function(e){ if (hasInParentsUntil(e.target,''game-again'',container)) { // container should be e.stopPropagation(); // available for this self.publish(''primo:evento''); } });

Estoy tratando de hacer la delegación de eventos en vanilla JS. Tengo un botón dentro de un contenedor como este

<div id="quiz"> <button id="game-again" class="game-again"><span class="icon-spinner icon"></span><span>Go again</span></button> </div>

Y siguiendo las bonitas instrucciones de David Walsh, estoy agregando un controlador de eventos a un antepasado del botón así:

this.container.addEventListener(''click'', function(e){ if (e.target && e.target.id == ''game-again'') { e.stopPropagation(); self.publish(''primo:evento''); } });

Donde this.container es el elemento #quiz. Esto funciona la mitad del tiempo, pero el resto del tiempo el objetivo del evento de clic es uno de los tramos dentro del botón, por lo que no se llama a mi controlador de eventos. ¿Cuál es la mejor manera de lidiar con esta situación?


Solución alternativa:

Agregar una clase a todos los elementos secundarios anidados ( .pointer-none )

/* css */ .pointer-none { pointer-events: none; }

Su marcado se convierte en

<div id="quiz"> <button id="game-again" class="game-again"> <span class="icon-spinner icon pointer-none"></span> <span class="pointer-none">Go again</span> </button> </div>

Con el puntero establecido en ninguno, el evento de clic no se activará en esos elementos.

https://css-tricks.com/slightly-careful-sub-elements-clickable-things/