Ce serait bien s'il y avait un lien vers smoe source d'informations utiles à ce sujet. 6 heures plus tard, c'est le top google pour "délégation d'événement dom". C'est peut-être un lien utile? Je ne suis pas tout à fait sûr: w3.org/TR/DOM-Level-2-Events/events.html
La délégation d'événement DOM est un mécanisme de réponse aux événements ui via un seul parent commun plutôt que chaque enfant, à travers la magie du "bouillonnement" d'événement (alias la propagation d'événement).
L'événement est envoyé à sa cible
EventTargetet tout écouteur d'événement qui s'y trouve est déclenché. Les
événements bouillonnants déclencheront alors tous les écouteurs d'événements supplémentaires trouvés en suivant la EventTargetchaîne parente du parent vers le haut , en vérifiant les écouteurs d'événements enregistrés sur chaque EventTarget successif. Cette propagation vers le haut se poursuivra jusqu'à et y compris le Document.
La propagation d'événements fournit la base de la délégation d'événements dans les navigateurs. Vous pouvez maintenant lier un gestionnaire d'événements à un seul élément parent, et ce gestionnaire sera exécuté chaque fois que l'événement se produit sur l'un de ses nœuds enfants (et l'un de leurs enfants à son tour). Il s'agit d'une délégation d'événement. En voici un exemple en pratique:
Avec cet exemple, si vous deviez cliquer sur l'un des <li>nœuds enfants , vous verriez une alerte "click!", même s'il n'y a pas de gestionnaire de clic lié à celui sur lequel <li>vous avez cliqué. Si nous nous lions onclick="..."à chacun, <li>vous obtiendriez le même effet.
Alors quel est l'avantage?
Imaginez que vous ayez maintenant besoin d'ajouter dynamiquement de nouveaux <li>éléments à la liste ci-dessus via la manipulation DOM:
var newLi = document.createElement('li');
newLi.innerHTML ='Four';
myUL.appendChild(newLi);
Sans utiliser la délégation d'événement, vous devez "relier" le "onclick"gestionnaire d'événements au nouvel <li>élément, afin qu'il agisse de la même manière que ses frères et sœurs. Avec la délégation d'événement, vous n'avez rien à faire. Ajoutez simplement le nouveau <li>à la liste et vous avez terminé.
C'est absolument fantastique pour les applications Web avec des gestionnaires d'événements liés à de nombreux éléments, où de nouveaux éléments sont créés et / ou supprimés dynamiquement dans le DOM. Avec la délégation d'événements, le nombre de liaisons d'événements peut être considérablement réduit en les déplaçant vers un élément parent commun, et le code qui crée dynamiquement de nouveaux éléments à la volée peut être découplé de la logique de liaison de leurs gestionnaires d'événements.
Un autre avantage de la délégation d'événements est que l'empreinte mémoire totale utilisée par les écouteurs d'événements diminue (car le nombre de liaisons d'événements diminue). Cela peut ne pas faire beaucoup de différence pour les petites pages qui se déchargent souvent (c'est-à-dire que l'utilisateur navigue souvent sur différentes pages). Mais pour les applications à longue durée de vie, cela peut être important. Il existe des situations vraiment difficiles à retrouver lorsque des éléments supprimés du DOM réclament toujours de la mémoire (c'est-à-dire qu'ils fuient), et souvent cette mémoire perdue est liée à une liaison d'événement. Avec la délégation d'événements, vous êtes libre de détruire les éléments enfants sans risquer d'oublier de "dissocier" leurs écouteurs d'événements (puisque l'auditeur est sur l'ancêtre). Ces types de fuites de mémoire peuvent alors être contenus (s'ils ne sont pas éliminés, ce qui est parfois difficile à faire. IE je vous regarde).
Voici de meilleurs exemples concrets de code de délégation d'événements:
J'ai un accès interdit à l'ouverture de votre troisième lien Délégation d'événements sans bibliothèque javascript et +1 pour votre dernier lien
bugwheels94
Bonjour, merci pour une bonne explication. Cependant, je suis toujours confus à propos d'un certain détail: la façon dont je comprends le flux d'événements de l'arborescence DOM (comme on peut le voir dans 3.1. Répartition des événements et flux d'événements DOM ) l'objet événement se propage jusqu'à ce qu'il atteigne l'élément cible, puis bouillonne. Comment se fait-il qu'il puisse atteindre les éléments enfants d'un nœud si le parent de ce nœud est la cible d'événement en question? par exemple, comment l'événement peut-il se propager à un<li> moment où il devrait s'arrêter <ul>? Si ma question n'est toujours pas claire ou a besoin d'un fil séparé, je serais heureux de vous obliger.
Aetos
@Aetos: > Comment se fait-il qu'il puisse atteindre les éléments enfants d'un nœud si le parent de ce nœud est la cible d'événement en question? Il ne peut pas, si je comprends bien. L'événement termine la phase 1 (capture) sur le parent de la cible, entre dans la phase 2 (cible) sur la cible elle-même, puis entre dans la phase 3 (bouillonnement) à partir du parent de la cible. Nulle part cela n'atteint un enfant de la cible.
Crescent Fresh du
@Crescent Fresh bien alors comment l'événement s'applique-t-il au nœud enfant s'il ne l'atteint jamais?
Aetos
1
Vraiment une excellente réponse. Merci d'avoir expliqué la délégation de l'événement avec des faits pertinents. Merci!
Kshitij Tiwari
30
La délégation d'événements vous permet d'éviter d'ajouter des écouteurs d'événements à des nœuds spécifiques; à la place, l'écouteur d'événements est ajouté à un parent. Cet écouteur d'événements analyse les événements bouillonnés pour trouver une correspondance avec les éléments enfants.
Exemple JavaScript:
Disons que nous avons un élément parent UL avec plusieurs éléments enfants:
Disons également que quelque chose doit se produire lorsque chaque élément enfant est cliqué. Vous pouvez ajouter un écouteur d'événement distinct à chaque élément LI individuel, mais que faire si des éléments LI sont fréquemment ajoutés et supprimés de la liste? Ajouter et supprimer des écouteurs d'événements serait un cauchemar, surtout si le code d'ajout et de suppression se trouve à différents endroits de votre application. La meilleure solution consiste à ajouter un écouteur d'événements à l'élément parent UL. Mais si vous ajoutez l'écouteur d'événements au parent, comment saurez-vous quel élément a été cliqué?
Simple: lorsque l'événement bouillonne jusqu'à l'élément UL, vous vérifiez la propriété cible de l'objet événement pour obtenir une référence au nœud cliqué réel. Voici un extrait de code JavaScript très basique qui illustre la délégation d'événements:
// Get the element, add a click listener...
document.getElementById("parent-list").addEventListener("click",function(e){// e.target is the clicked element!// If it was a list itemif(e.target && e.target.nodeName =="LI"){// List item found! Output the ID!
console.log("List item ", e.target.id.replace("post-")," was clicked!");}});
Commencez par ajouter un écouteur d'événements Click à l'élément parent. Lorsque l'écouteur d'événements est déclenché, vérifiez l'élément d'événement pour vous assurer qu'il s'agit du type d'élément auquel réagir. S'il s'agit d'un élément LI, boom: nous avons ce dont nous avons besoin! Si ce n'est pas un élément que nous voulons, l'événement peut être ignoré. Cet exemple est assez simple - UL et LI est une comparaison simple. Essayons quelque chose de plus difficile. Ayons un DIV parent avec beaucoup d'enfants, mais tout ce qui nous intéresse, c'est une balise A avec la classe CSS classA:
// Get the parent DIV, add click listener...
document.getElementById("myDiv").addEventListener("click",function(e){// e.target was the clicked elementif(e.target && e.target.nodeName =="A"){// Get the CSS classesvar classes = e.target.className.split(" ");// Search for the CSS class!if(classes){// For every CSS class the element has...for(var x =0; x < classes.length; x++){// If it has the CSS class we want...if(classes[x]=="classA"){// Bingo!
console.log("Anchor element clicked!");// Now do something here....}}}}});
La délégation d'événement dom est quelque chose de différent de la définition de l'informatique.
Il fait référence à la gestion des événements de propagation à partir de nombreux éléments, comme les cellules d'un tableau, à partir d'un objet parent, comme le tableau. Il peut garder le code plus simple, en particulier lors de l'ajout ou de la suppression d'éléments, et économise de la mémoire.
Délégation est une technique où un objet exprime un certain comportement à l'extérieur mais délègue en réalité la responsabilité de l'implémentation de ce comportement à un objet associé. Cela semble au début très similaire au modèle de proxy, mais il sert un objectif très différent. La délégation est un mécanisme d'abstraction qui centralise le comportement des objets (méthode).
De manière générale: utiliser la délégation comme alternative à l'héritage. L'héritage est une bonne stratégie, quand une relation étroite existe entre l'objet parent et l'enfant, cependant, l'héritage couple très étroitement les objets. Souvent, la délégation est le moyen le plus flexible d'exprimer une relation entre les classes.
Ce modèle est également appelé «chaînes proxy». Plusieurs autres modèles de conception utilisent la délégation - l'état, la stratégie et les modèles de visiteurs en dépendent.
Bonne explication. Dans l'exemple du <ul> avec plusieurs <li> enfants, apparemment les <li> sont ceux qui gèrent la logique de clic, mais ce n'est pas comme ça parce qu'ils "délèguent" cette logique au père <ul>
Juanma Menendez
6
Le concept de délégation
S'il y a beaucoup d'éléments à l'intérieur d'un parent et que vous souhaitez gérer des événements sur eux, ne liez pas de gestionnaires à chaque élément. Au lieu de cela, liez le gestionnaire unique à son parent et récupérez l'enfant à partir de event.target. Ce site fournit des informations utiles sur la façon de mettre en œuvre la délégation d'événements.
http://javascript.info/tutorial/event-delegation
La délégation d'événement gère un événement qui bouillonne aide d'un gestionnaire d'événements sur un élément de conteneur, mais n'active le comportement du gestionnaire d'événements que si l'événement s'est produit sur un élément du conteneur qui correspond à une condition donnée. Cela peut simplifier la gestion des événements sur les éléments du conteneur.
Par exemple, supposons que vous souhaitiez gérer un clic sur n'importe quelle cellule d'un tableau dans un grand tableau. Tu pourrais écrire une boucle pour connecter un gestionnaire de clics à chaque cellule ... ou vous pouvez raccorder un gestionnaire de clics sur la table et utiliser la délégation d'événements pour la déclencher uniquement pour les cellules de tableau (et non les en-têtes de tableau, ou les espaces dans un ranger autour des cellules, etc.).
Il est également utile lorsque vous allez ajouter et supprimer des éléments du conteneur, car vous n'avez pas à vous soucier d'ajouter et de supprimer des gestionnaires d'événements sur ces éléments; accrochez simplement l'événement sur le conteneur et gérez l'événement lorsqu'il bouillonne.
Voici un exemple simple (il est intentionnellement verbeux pour permettre une explication en ligne): Gérer un clic sur n'importe quel tdélément d'une table de conteneur:
// Handle the event on the container
document.getElementById("container").addEventListener("click",function(event){// Find out if the event targeted or bubbled through a `td` en route to this container elementvar element = event.target;var target;while(element &&!target){if(element.matches("td")){// Found a `td` within the container!
target = element;}else{// Not foundif(element ===this){// We've reached the container, stop
element =null;}else{// Go to the next parent in the ancestry
element = element.parentNode;}}}if(target){
console.log("You clicked a td: "+ target.textContent);}else{
console.log("That wasn't a td in the container table");}});
Avant d'entrer dans les détails, rappelons-nous comment fonctionnent les événements DOM.
Les événements DOM sont distribués du document vers l'élément cible (la phase de capture ), puis remontent de l'élément cible vers le document (la phase de propagation ). Ce graphique dans l'ancienne spécification des événements DOM3 (désormais remplacé, mais le graphique est toujours valide) le montre très bien:
Tous les événements ne bouillonnent pas, mais la plupart le font, y compris click.
Les commentaires de l'exemple de code ci-dessus décrivent son fonctionnement. matchesvérifie si un élément correspond à un sélecteur CSS, mais bien sûr, vous pouvez vérifier si quelque chose correspond à vos critères d'une autre manière si vous ne souhaitez pas utiliser un sélecteur CSS.
Ce code est écrit pour appeler les étapes individuelles verbalement, mais sur des navigateurs vaguement modernes (et aussi sur IE si vous utilisez un polyfill), vous pouvez utiliser closestet containsau lieu de la boucle:
var target = event.target.closest("td");
console.log("You clicked a td: "+ target.textContent);}else{
console.log("That wasn't a td in the container table");}
// Handle the event on the container
document.getElementById("container").addEventListener("click",function(event){var target = event.target.closest("td");if(target &&this.contains(target)){
console.log("You clicked a td: "+ target.textContent);}else{
console.log("That wasn't a td in the container table");}});
closestvérifie l'élément sur lequel vous l'appelez pour voir s'il correspond au sélecteur CSS donné et, si c'est le cas, retourne ce même élément; sinon, il vérifie l'élément parent pour voir s'il correspond, et renvoie le parent si c'est le cas; sinon, il vérifie le parent du parent, etc. Il trouve donc l'élément "le plus proche" dans la liste des ancêtres qui correspond au sélecteur. Étant donné que cela peut dépasser l'élément conteneur, le code ci-dessus utilise containspour vérifier que si un élément correspondant a été trouvé, il se trouve dans le conteneur - car en accrochant l'événement sur le conteneur, vous avez indiqué que vous ne souhaitez gérer que les éléments dans ce conteneur. .
Pour revenir à notre exemple de tableau, cela signifie que si vous avez un tableau dans une cellule de tableau, il ne correspondra pas à la cellule de tableau contenant le tableau:
// Handle the event on the container
document.getElementById("container").addEventListener("click",function(event){var target = event.target.closest("td");if(target &&this.contains(target)){
console.log("You clicked a td: "+ target.textContent);}else{
console.log("That wasn't a td in the container table");}});
<!-- The table wrapped around the #container table --><table><tbody><tr><td><!-- This cell doesn't get matched, thanks to the `this.contains(target)` check --><tableid="container"><thead><tr><th>Language</th><th>1</th><th>2</th><th>3</th></tr></thead><tbody><tr><thclass="rowheader">English</th><td>one</td><td>two</td><td>three</td></tr><tr><thclass="rowheader">Español</th><td>uno</td><td>dos</td><td>tres</td></tr><tr><thclass="rowheader">Italiano</th><td>uno</td><td>due</td><td>tre</td></tr></tbody></table></td><td>
This is next to the container table
</td></tr></tbody></table>
C'est essentiellement la façon dont l'association est faite à l'élément. .clicks'applique au DOM actuel, tandis que .on(en utilisant la délégation) continuera d'être valide pour les nouveaux éléments ajoutés au DOM après l'association d'événements.
Quel est le meilleur à utiliser, je dirais que cela dépend du cas.
Pour comprendre la délégation d'événements, nous devons d'abord savoir pourquoi et quand nous avons réellement besoin ou voulons une délégation d'événements.
Il peut y avoir de nombreux cas, mais discutons de deux grands cas d'utilisation pour la délégation d'événements. 1. Le premier cas est lorsque nous avons un élément avec beaucoup d'éléments enfants qui nous intéresse. Dans ce cas, au lieu d'ajouter un gestionnaire d'événements à tous ces éléments enfants, nous l'ajoutons simplement à l'élément parent, puis déterminons sur quel élément enfant l'événement a été déclenché.
2.Le deuxième cas d'utilisation pour la délégation d'événements est lorsque nous voulons qu'un gestionnaire d'événements soit attaché à un élément qui n'est pas encore dans le DOM lorsque notre page est chargée. C'est, bien sûr, parce que nous ne pouvons pas ajouter un gestionnaire d'événements à quelque chose qui n'est pas sur notre page, donc dans un cas de dépréciation que nous codons.
Supposons que vous ayez une liste de 0, 10 ou 100 éléments dans le DOM lorsque vous chargez votre page et que d'autres éléments attendent dans votre main pour être ajoutés à la liste. Il n'y a donc aucun moyen d'attacher un gestionnaire d'événements pour les futurs éléments ou ces éléments ne sont pas encore ajoutés dans le DOM, et il peut également y avoir beaucoup d'éléments, il ne serait donc pas utile d'avoir un gestionnaire d'événements attaché à chacun d'eux.
Délégation d'événement
Très bien, donc pour parler de délégation d'événement, le premier concept dont nous devons réellement parler est le bouillonnement d'événement.
Bulle d'événement: la bulle d'
événement signifie que lorsqu'un événement est déclenché ou déclenché sur un élément DOM, par exemple en cliquant sur notre bouton ici sur l'image ci-dessous, le même événement exact est également déclenché sur tous les éléments parents.
L'événement est d'abord déclenché sur le bouton, mais il sera également déclenché sur tous les éléments parents un par un, il déclenchera également le paragraphe dans la section l'élément principal et en fait tout le chemin dans une arborescence DOM jusqu'à l'élément HTML qui est la racine. Nous disons donc que l'événement bouillonne à l'intérieur de l'arborescence DOM, et c'est pourquoi il est appelé bouillonnement.
Élément cible: l'élément sur lequel l'événement a été déclenché pour la première fois, appelé l'élément cible, de sorte que l'élément qui a provoqué l'événement, est appelé l'élément cible. Dans notre exemple ci-dessus, c'est bien sûr le bouton sur lequel vous avez cliqué. La partie importante est que cet élément cible est stocké en tant que propriété dans l'objet événement, cela signifie que tous les éléments parents sur lesquels l'événement se déclenchera également connaîtront l'élément cible de l'événement, donc où l'événement a été déclenché pour la première fois.
Cela nous amène à la délégation d'événements parce que si l'événement bouillonne dans l'arborescence DOM, et si nous savons où l'événement a été déclenché, nous pouvons simplement attacher un gestionnaire d'événements à un élément parent et attendre que l'événement se propage, et nous pouvons puis faites tout ce que nous voulions faire avec notre élément cible. Cette technique est appelée délégation d'événements. Dans cet exemple, nous pourrions simplement ajouter le gestionnaire d'événements à l'élément principal.
Très bien, encore une fois, la délégation d'événements ne consiste pas à configurer le gestionnaire d'événements sur l'élément d'origine qui nous intéresse, mais à le rattacher à un élément parent et, fondamentalement, à y attraper l'événement car il bouillonne. Nous pouvons ensuite agir sur l'élément qui nous intéresse en utilisant la propriété d'élément cible.
Exemple:
Supposons maintenant que nous avons deux éléments de liste dans notre page, après avoir ajouté des éléments dans cette liste par programme, nous voulons en supprimer un ou plusieurs. En utilisant la technique de délégation d'événements, nous pouvons atteindre notre objectif facilement.
<div class="body"><div class="top"></div><div class="bottom"><div class="other"><!-- other bottom elements --></div><div class="container clearfix"><div class="income"><h2 class="icome__title">Income</h2><div class="income__list"><!-- list items --></div></div><div class="expenses"><h2 class="expenses__title">Expenses</h2><div class="expenses__list"><!-- list items --></div></div></div></div></div>
Ajout d'éléments dans cette liste:
constDOMstrings={
type:{
income:'inc',
expense:'exp'},
incomeContainer:'.income__list',
expenseContainer:'.expenses__list',
container:'.container'}var addListItem =function(obj, type){//create html string with the place holdervar html, element;if(type===DOMstrings.type.income){
element =DOMstrings.incomeContainer
html =`<div class="item clearfix" id="inc-${obj.id}"><div class="item__description">${obj.descripiton}</div><div class="right clearfix"><div class="item__value">${obj.value}</div><div class="item__delete"><button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button></div></div></div>`}elseif(type ===DOMstrings.type.expense){
element=DOMstrings.expenseContainer;
html =`<div class="item clearfix" id="exp-${obj.id}"><div class="item__description">${obj.descripiton}</div><div class="right clearfix"><div class="item__value">${obj.value}</div><div class="item__percentage">21%</div><div class="item__delete"><button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button></div></div></div>`}var htmlObject = document.createElement('div');
htmlObject.innerHTML=html;
document.querySelector(element).insertAdjacentElement('beforeend', htmlObject);}
Supprimer des éléments:
var ctrlDeleteItem =function(event){// var itemId = event.target.parentNode.parentNode.parentNode.parentNode.id;var parent = event.target.parentNode;var splitId, type, ID;while(parent.id===""){
parent = parent.parentNode
}if(parent.id){
splitId = parent.id.split('-');
type = splitId[0];
ID=parseInt(splitId[1]);}
deleteItem(type, ID);
deleteListItem(parent.id);}var deleteItem =function(type, id){var ids, index;
ids = data.allItems[type].map(function(current){return current.id;});
index = ids.indexOf(id);if(index>-1){
data.allItems[type].splice(index,1);}}var deleteListItem =function(selectorID){var element = document.getElementById(selectorID);
element.parentNode.removeChild(element);}
Un délégué en C # est similaire à un pointeur de fonction en C ou C ++. L'utilisation d'un délégué permet au programmeur d'encapsuler une référence à une méthode à l'intérieur d'un objet délégué. L'objet délégué peut ensuite être passé au code qui peut appeler la méthode référencée, sans avoir à savoir au moment de la compilation quelle méthode sera invoquée.
Je ne vais pas voter contre, car c'était probablement une bonne réponse à la question d'origine, mais la question concerne maintenant spécifiquement la délégation des événements DOM et Javascript
iandotkelly
1
La délégation d'événement utilise deux fonctionnalités souvent négligées des événements JavaScript: la propagation d'événements et l'élément cible. Lorsqu'un événement est déclenché sur un élément, par exemple un clic de souris sur un bouton, le même événement est également déclenché sur tous les ancêtres de cet élément. . Ce processus est connu sous le nom de bulles d’événement; l'événement monte de l'élément d'origine vers le haut de l'arborescence DOM.
Imaginez un tableau HTML avec 10 colonnes et 100 lignes dans lequel vous voulez que quelque chose se passe lorsque l'utilisateur clique sur une cellule du tableau. Par exemple, j'ai dû une fois rendre chaque cellule d'un tableau de cette taille modifiable lorsque vous cliquez dessus. L'ajout de gestionnaires d'événements à chacune des 1000 cellules serait un problème de performances majeur et, potentiellement, une source de fuites de mémoire provoquant un plantage du navigateur. À la place, à l'aide de la délégation d'événements, vous n'ajouteriez qu'un seul gestionnaire d'événements à l'élément de table, intercepteriez l'événement de clic et déterminer la cellule sur laquelle vous avez cliqué.
Attachez un écouteur d'événements à un élément parent qui se déclenche lorsqu'un événement se produit sur un élément enfant.
Propagation d'événements
Lorsqu'un événement se déplace dans le DOM de l'enfant vers un élément parent, cela s'appelle la propagation d'événements , car l'événement se propage ou se déplace dans le DOM.
Dans cet exemple, un événement (onclick) d'un bouton est passé au paragraphe parent.
$(document).ready(function(){
$(".spoiler span").hide();/* add event onclick on parent (.spoiler) and delegate its event to child (button) */
$(".spoiler").on("click","button",function(){
$(".spoiler button").hide();
$(".spoiler span").show();});});
Réponses:
La délégation d'événement DOM est un mécanisme de réponse aux événements ui via un seul parent commun plutôt que chaque enfant, à travers la magie du "bouillonnement" d'événement (alias la propagation d'événement).
Lorsqu'un événement est déclenché sur un élément, les événements suivants se produisent :
La propagation d'événements fournit la base de la délégation d'événements dans les navigateurs. Vous pouvez maintenant lier un gestionnaire d'événements à un seul élément parent, et ce gestionnaire sera exécuté chaque fois que l'événement se produit sur l'un de ses nœuds enfants (et l'un de leurs enfants à son tour). Il s'agit d'une délégation d'événement. En voici un exemple en pratique:
Avec cet exemple, si vous deviez cliquer sur l'un des
<li>
nœuds enfants , vous verriez une alerte"click!"
, même s'il n'y a pas de gestionnaire de clic lié à celui sur lequel<li>
vous avez cliqué. Si nous nous lionsonclick="..."
à chacun,<li>
vous obtiendriez le même effet.Alors quel est l'avantage?
Imaginez que vous ayez maintenant besoin d'ajouter dynamiquement de nouveaux
<li>
éléments à la liste ci-dessus via la manipulation DOM:Sans utiliser la délégation d'événement, vous devez "relier" le
"onclick"
gestionnaire d'événements au nouvel<li>
élément, afin qu'il agisse de la même manière que ses frères et sœurs. Avec la délégation d'événement, vous n'avez rien à faire. Ajoutez simplement le nouveau<li>
à la liste et vous avez terminé.C'est absolument fantastique pour les applications Web avec des gestionnaires d'événements liés à de nombreux éléments, où de nouveaux éléments sont créés et / ou supprimés dynamiquement dans le DOM. Avec la délégation d'événements, le nombre de liaisons d'événements peut être considérablement réduit en les déplaçant vers un élément parent commun, et le code qui crée dynamiquement de nouveaux éléments à la volée peut être découplé de la logique de liaison de leurs gestionnaires d'événements.
Un autre avantage de la délégation d'événements est que l'empreinte mémoire totale utilisée par les écouteurs d'événements diminue (car le nombre de liaisons d'événements diminue). Cela peut ne pas faire beaucoup de différence pour les petites pages qui se déchargent souvent (c'est-à-dire que l'utilisateur navigue souvent sur différentes pages). Mais pour les applications à longue durée de vie, cela peut être important. Il existe des situations vraiment difficiles à retrouver lorsque des éléments supprimés du DOM réclament toujours de la mémoire (c'est-à-dire qu'ils fuient), et souvent cette mémoire perdue est liée à une liaison d'événement. Avec la délégation d'événements, vous êtes libre de détruire les éléments enfants sans risquer d'oublier de "dissocier" leurs écouteurs d'événements (puisque l'auditeur est sur l'ancêtre). Ces types de fuites de mémoire peuvent alors être contenus (s'ils ne sont pas éliminés, ce qui est parfois difficile à faire. IE je vous regarde).
Voici de meilleurs exemples concrets de code de délégation d'événements:
focus
etblur
(qui ne bouillonnent pas )la source
<li>
moment où il devrait s'arrêter<ul>
? Si ma question n'est toujours pas claire ou a besoin d'un fil séparé, je serais heureux de vous obliger.La délégation d'événements vous permet d'éviter d'ajouter des écouteurs d'événements à des nœuds spécifiques; à la place, l'écouteur d'événements est ajouté à un parent. Cet écouteur d'événements analyse les événements bouillonnés pour trouver une correspondance avec les éléments enfants.
Exemple JavaScript:
Disons que nous avons un élément parent UL avec plusieurs éléments enfants:
Disons également que quelque chose doit se produire lorsque chaque élément enfant est cliqué. Vous pouvez ajouter un écouteur d'événement distinct à chaque élément LI individuel, mais que faire si des éléments LI sont fréquemment ajoutés et supprimés de la liste? Ajouter et supprimer des écouteurs d'événements serait un cauchemar, surtout si le code d'ajout et de suppression se trouve à différents endroits de votre application. La meilleure solution consiste à ajouter un écouteur d'événements à l'élément parent UL. Mais si vous ajoutez l'écouteur d'événements au parent, comment saurez-vous quel élément a été cliqué?
Simple: lorsque l'événement bouillonne jusqu'à l'élément UL, vous vérifiez la propriété cible de l'objet événement pour obtenir une référence au nœud cliqué réel. Voici un extrait de code JavaScript très basique qui illustre la délégation d'événements:
Commencez par ajouter un écouteur d'événements Click à l'élément parent. Lorsque l'écouteur d'événements est déclenché, vérifiez l'élément d'événement pour vous assurer qu'il s'agit du type d'élément auquel réagir. S'il s'agit d'un élément LI, boom: nous avons ce dont nous avons besoin! Si ce n'est pas un élément que nous voulons, l'événement peut être ignoré. Cet exemple est assez simple - UL et LI est une comparaison simple. Essayons quelque chose de plus difficile. Ayons un DIV parent avec beaucoup d'enfants, mais tout ce qui nous intéresse, c'est une balise A avec la classe CSS classA:
http://davidwalsh.name/event-delegate
la source
La délégation d'événement dom est quelque chose de différent de la définition de l'informatique.
Il fait référence à la gestion des événements de propagation à partir de nombreux éléments, comme les cellules d'un tableau, à partir d'un objet parent, comme le tableau. Il peut garder le code plus simple, en particulier lors de l'ajout ou de la suppression d'éléments, et économise de la mémoire.
la source
Délégation est une technique où un objet exprime un certain comportement à l'extérieur mais délègue en réalité la responsabilité de l'implémentation de ce comportement à un objet associé. Cela semble au début très similaire au modèle de proxy, mais il sert un objectif très différent. La délégation est un mécanisme d'abstraction qui centralise le comportement des objets (méthode).
De manière générale: utiliser la délégation comme alternative à l'héritage. L'héritage est une bonne stratégie, quand une relation étroite existe entre l'objet parent et l'enfant, cependant, l'héritage couple très étroitement les objets. Souvent, la délégation est le moyen le plus flexible d'exprimer une relation entre les classes.
Ce modèle est également appelé «chaînes proxy». Plusieurs autres modèles de conception utilisent la délégation - l'état, la stratégie et les modèles de visiteurs en dépendent.
la source
Le concept de délégation
S'il y a beaucoup d'éléments à l'intérieur d'un parent et que vous souhaitez gérer des événements sur eux, ne liez pas de gestionnaires à chaque élément. Au lieu de cela, liez le gestionnaire unique à son parent et récupérez l'enfant à partir de event.target. Ce site fournit des informations utiles sur la façon de mettre en œuvre la délégation d'événements. http://javascript.info/tutorial/event-delegation
la source
La délégation d'événement gère un événement qui bouillonne aide d'un gestionnaire d'événements sur un élément de conteneur, mais n'active le comportement du gestionnaire d'événements que si l'événement s'est produit sur un élément du conteneur qui correspond à une condition donnée. Cela peut simplifier la gestion des événements sur les éléments du conteneur.
Par exemple, supposons que vous souhaitiez gérer un clic sur n'importe quelle cellule d'un tableau dans un grand tableau. Tu pourrais écrire une boucle pour connecter un gestionnaire de clics à chaque cellule ... ou vous pouvez raccorder un gestionnaire de clics sur la table et utiliser la délégation d'événements pour la déclencher uniquement pour les cellules de tableau (et non les en-têtes de tableau, ou les espaces dans un ranger autour des cellules, etc.).
Il est également utile lorsque vous allez ajouter et supprimer des éléments du conteneur, car vous n'avez pas à vous soucier d'ajouter et de supprimer des gestionnaires d'événements sur ces éléments; accrochez simplement l'événement sur le conteneur et gérez l'événement lorsqu'il bouillonne.
Voici un exemple simple (il est intentionnellement verbeux pour permettre une explication en ligne): Gérer un clic sur n'importe quel
td
élément d'une table de conteneur:Avant d'entrer dans les détails, rappelons-nous comment fonctionnent les événements DOM.
Les événements DOM sont distribués du document vers l'élément cible (la phase de capture ), puis remontent de l'élément cible vers le document (la phase de propagation ). Ce graphique dans l'ancienne spécification des événements DOM3 (désormais remplacé, mais le graphique est toujours valide) le montre très bien:
Tous les événements ne bouillonnent pas, mais la plupart le font, y compris
click
.Les commentaires de l'exemple de code ci-dessus décrivent son fonctionnement.
matches
vérifie si un élément correspond à un sélecteur CSS, mais bien sûr, vous pouvez vérifier si quelque chose correspond à vos critères d'une autre manière si vous ne souhaitez pas utiliser un sélecteur CSS.Ce code est écrit pour appeler les étapes individuelles verbalement, mais sur des navigateurs vaguement modernes (et aussi sur IE si vous utilisez un polyfill), vous pouvez utiliser
closest
etcontains
au lieu de la boucle:Exemple en direct:
Afficher l'extrait de code
closest
vérifie l'élément sur lequel vous l'appelez pour voir s'il correspond au sélecteur CSS donné et, si c'est le cas, retourne ce même élément; sinon, il vérifie l'élément parent pour voir s'il correspond, et renvoie le parent si c'est le cas; sinon, il vérifie le parent du parent, etc. Il trouve donc l'élément "le plus proche" dans la liste des ancêtres qui correspond au sélecteur. Étant donné que cela peut dépasser l'élément conteneur, le code ci-dessus utilisecontains
pour vérifier que si un élément correspondant a été trouvé, il se trouve dans le conteneur - car en accrochant l'événement sur le conteneur, vous avez indiqué que vous ne souhaitez gérer que les éléments dans ce conteneur. .Pour revenir à notre exemple de tableau, cela signifie que si vous avez un tableau dans une cellule de tableau, il ne correspondra pas à la cellule de tableau contenant le tableau:
Afficher l'extrait de code
la source
C'est essentiellement la façon dont l'association est faite à l'élément.
.click
s'applique au DOM actuel, tandis que.on
(en utilisant la délégation) continuera d'être valide pour les nouveaux éléments ajoutés au DOM après l'association d'événements.Quel est le meilleur à utiliser, je dirais que cela dépend du cas.
Exemple:
.Cliquez sur l'événement:
Événement .on:
Notez que j'ai séparé le sélecteur dans le .on. Je vais vous expliquer pourquoi.
Supposons qu'après cette association, procédons comme suit:
C'est là que vous remarquerez la différence.
Si l'événement a été associé via .click, la tâche 5 n'obéira pas à l'événement click et ne sera donc pas supprimé.
S'il a été associé via .on, avec le sélecteur séparé, il obéira.
la source
Pour comprendre la délégation d'événements, nous devons d'abord savoir pourquoi et quand nous avons réellement besoin ou voulons une délégation d'événements.
Il peut y avoir de nombreux cas, mais discutons de deux grands cas d'utilisation pour la délégation d'événements. 1. Le premier cas est lorsque nous avons un élément avec beaucoup d'éléments enfants qui nous intéresse. Dans ce cas, au lieu d'ajouter un gestionnaire d'événements à tous ces éléments enfants, nous l'ajoutons simplement à l'élément parent, puis déterminons sur quel élément enfant l'événement a été déclenché.
2.Le deuxième cas d'utilisation pour la délégation d'événements est lorsque nous voulons qu'un gestionnaire d'événements soit attaché à un élément qui n'est pas encore dans le DOM lorsque notre page est chargée. C'est, bien sûr, parce que nous ne pouvons pas ajouter un gestionnaire d'événements à quelque chose qui n'est pas sur notre page, donc dans un cas de dépréciation que nous codons.
Supposons que vous ayez une liste de 0, 10 ou 100 éléments dans le DOM lorsque vous chargez votre page et que d'autres éléments attendent dans votre main pour être ajoutés à la liste. Il n'y a donc aucun moyen d'attacher un gestionnaire d'événements pour les futurs éléments ou ces éléments ne sont pas encore ajoutés dans le DOM, et il peut également y avoir beaucoup d'éléments, il ne serait donc pas utile d'avoir un gestionnaire d'événements attaché à chacun d'eux.
Délégation d'événement
Très bien, donc pour parler de délégation d'événement, le premier concept dont nous devons réellement parler est le bouillonnement d'événement.
Bulle d'événement: la bulle d' événement signifie que lorsqu'un événement est déclenché ou déclenché sur un élément DOM, par exemple en cliquant sur notre bouton ici sur l'image ci-dessous, le même événement exact est également déclenché sur tous les éléments parents.
L'événement est d'abord déclenché sur le bouton, mais il sera également déclenché sur tous les éléments parents un par un, il déclenchera également le paragraphe dans la section l'élément principal et en fait tout le chemin dans une arborescence DOM jusqu'à l'élément HTML qui est la racine. Nous disons donc que l'événement bouillonne à l'intérieur de l'arborescence DOM, et c'est pourquoi il est appelé bouillonnement.
Élément cible: l'élément sur lequel l'événement a été déclenché pour la première fois, appelé l'élément cible, de sorte que l'élément qui a provoqué l'événement, est appelé l'élément cible. Dans notre exemple ci-dessus, c'est bien sûr le bouton sur lequel vous avez cliqué. La partie importante est que cet élément cible est stocké en tant que propriété dans l'objet événement, cela signifie que tous les éléments parents sur lesquels l'événement se déclenchera également connaîtront l'élément cible de l'événement, donc où l'événement a été déclenché pour la première fois.
Cela nous amène à la délégation d'événements parce que si l'événement bouillonne dans l'arborescence DOM, et si nous savons où l'événement a été déclenché, nous pouvons simplement attacher un gestionnaire d'événements à un élément parent et attendre que l'événement se propage, et nous pouvons puis faites tout ce que nous voulions faire avec notre élément cible. Cette technique est appelée délégation d'événements. Dans cet exemple, nous pourrions simplement ajouter le gestionnaire d'événements à l'élément principal.
Très bien, encore une fois, la délégation d'événements ne consiste pas à configurer le gestionnaire d'événements sur l'élément d'origine qui nous intéresse, mais à le rattacher à un élément parent et, fondamentalement, à y attraper l'événement car il bouillonne. Nous pouvons ensuite agir sur l'élément qui nous intéresse en utilisant la propriété d'élément cible.
Exemple: Supposons maintenant que nous avons deux éléments de liste dans notre page, après avoir ajouté des éléments dans cette liste par programme, nous voulons en supprimer un ou plusieurs. En utilisant la technique de délégation d'événements, nous pouvons atteindre notre objectif facilement.
Ajout d'éléments dans cette liste:
Supprimer des éléments:
la source
Un délégué en C # est similaire à un pointeur de fonction en C ou C ++. L'utilisation d'un délégué permet au programmeur d'encapsuler une référence à une méthode à l'intérieur d'un objet délégué. L'objet délégué peut ensuite être passé au code qui peut appeler la méthode référencée, sans avoir à savoir au moment de la compilation quelle méthode sera invoquée.
Voir ce lien -> http://www.akadia.com/services/dotnet_delegates_and_events.html
la source
La délégation d'événement utilise deux fonctionnalités souvent négligées des événements JavaScript: la propagation d'événements et l'élément cible. Lorsqu'un événement est déclenché sur un élément, par exemple un clic de souris sur un bouton, le même événement est également déclenché sur tous les ancêtres de cet élément. . Ce processus est connu sous le nom de bulles d’événement; l'événement monte de l'élément d'origine vers le haut de l'arborescence DOM.
Imaginez un tableau HTML avec 10 colonnes et 100 lignes dans lequel vous voulez que quelque chose se passe lorsque l'utilisateur clique sur une cellule du tableau. Par exemple, j'ai dû une fois rendre chaque cellule d'un tableau de cette taille modifiable lorsque vous cliquez dessus. L'ajout de gestionnaires d'événements à chacune des 1000 cellules serait un problème de performances majeur et, potentiellement, une source de fuites de mémoire provoquant un plantage du navigateur. À la place, à l'aide de la délégation d'événements, vous n'ajouteriez qu'un seul gestionnaire d'événements à l'élément de table, intercepteriez l'événement de clic et déterminer la cellule sur laquelle vous avez cliqué.
la source
Attachez un écouteur d'événements à un élément parent qui se déclenche lorsqu'un événement se produit sur un élément enfant.
Propagation d'événementsLorsqu'un événement se déplace dans le DOM de l'enfant vers un élément parent, cela s'appelle la propagation d'événements , car l'événement se propage ou se déplace dans le DOM.
Dans cet exemple, un événement (onclick) d'un bouton est passé au paragraphe parent.
Codepen
la source