Implémentation du classeur "en direct" de jQuery avec Javascript natif

J'essaie de trouver comment lier un événement à des éléments dynamiquement créés. J'ai besoin que l'événement persiste sur l'élément, même après qu'il soit détruit et régénéré.

De toute évidence, la fonction en direct de jQuery est facile, mais à quoi ressembleraient-ils implémentés avec un Javascript natif?

Voici un exemple 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); }); 

L'idée de base est que vous souhaitez attacher un gestionnaire d'événements au document et laisser l'événement exploser le DOM. Ensuite, vérifiez la propriété event.target pour voir si elle correspond aux critères souhaités (dans ce cas, juste que l' id de l'élément).

Modifier:

@shabunc a découvert un très gros problème avec ma solution: les événements sur les éléments enfants ne seront pas détectés correctement. Une façon de résoudre ce problème est de regarder les éléments ancêtres pour voir si l' id spécifié est déjà id :

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

En plus du post d'Andrew et du commentaire de Binyamin, peut-être que c'est une option:

Avec cela, vous pouvez utiliser 'nav .item a' comme sélecteur. Basé sur le code d'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'); });