Quelle est la différence entre le bouillonnement et la capture d'événements ? Quand faut-il utiliser le bullage ou la capture ?
useCapture
désormais pris en charge dans IE >= 9. fuente
Quelle est la différence entre le bouillonnement et la capture d'événements ? Quand faut-il utiliser le bullage ou la capture ?
Le bullage et la capture d'événements sont deux modes de propagation d'événements dans l'API HTML DOM, lorsqu'un événement se produit dans un élément à l'intérieur d'un autre élément, et que les deux éléments ont enregistré un handle pour cet événement. Le mode de propagation des événements détermine dans dans quel ordre les éléments reçoivent l'événement .
Avec le bullage, l'événement est d'abord capturé et traité par l'élément le plus interne, puis propagé aux éléments externes.
Avec la capture, l'événement est d'abord capturé par l'élément le plus extérieur et propagé aux éléments intérieurs.
La capture est également appelée "trickling", ce qui permet de se souvenir de l'ordre de propagation :
ruisseler vers le bas, bouillonner vers le haut
Autrefois, Netscape préconisait la capture d'événements, tandis que Microsoft favorisait le bouillonnement d'événements. Les deux font partie du W3C Événements du modèle objet du document standard (2000).
IE < 9 utilise uniquement le bouillonnement d'événements alors que IE9+ et tous les principaux navigateurs prennent en charge les deux. D'autre part, le les performances du bullage d'événement peuvent être légèrement inférieures pour les DOM complexes.
Nous pouvons utiliser le addEventListener(type, listener, useCapture)
pour enregistrer des gestionnaires d'événements en mode bulle (par défaut) ou en mode capture. Pour utiliser le modèle de capture, passez le troisième argument en tant que true
.
<div>
<ul>
<li></li>
</ul>
</div>
Dans la structure ci-dessus, supposons qu'un événement de clic s'est produit dans le champ li
élément.
Dans le modèle de capture, l'événement sera traité par la fonction div
d'abord (les gestionnaires d'événements de clics dans le div
tirera en premier), puis dans le ul
puis en dernier lieu dans l'élément cible, li
.
Dans le modèle de bouillonnement, c'est l'inverse qui se produit : l'événement est d'abord traité par la fonction li
puis par le ul
et enfin par le div
élément.
Pour plus d'informations, voir
Dans l'exemple ci-dessous, si vous cliquez sur l'un des éléments mis en évidence, vous pouvez voir que la phase de capture du flux de propagation des événements se produit en premier, suivie de la phase de bullage.
var logElement = document.getElementById('log');
function log(msg) {
logElement.innerHTML += ('<p>' + msg + '</p>');
}
function capture() {
log('capture: ' + this.firstChild.nodeValue.trim());
}
function bubble() {
log('bubble: ' + this.firstChild.nodeValue.trim());
}
function clearOutput() {
logElement.innerHTML = "";
}
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', capture, true);
divs[i].addEventListener('click', bubble, false);
}
var clearButton = document.getElementById('clear');
clearButton.addEventListener('click', clearOutput);
p {
line-height: 0;
}
div {
display:inline-block;
padding: 5px;
background: #fff;
border: 1px solid #aaa;
cursor: pointer;
}
div:hover {
border: 1px solid #faa;
background: #fdd;
}
<div>1
<div>2
<div>3
<div>4
<div>5</div>
</div>
</div>
</div>
</div>
<button id="clear">clear output</button>
<section id="log"></section>
Je sais qu'il est trop tard pour faire un commentaire mais j'ai trouvé un bel article ici. catcode.com/domcontent/events/capture.html
Est triclkling
la même chose que capturing
? Crockford parle de Trickling v. Bubbling
dans ce discours vidéo - youtube.com/watch?v=Fv9qT9joc0M&list=PL7664379246A246CB autour de 1 hr 5 minutes
.
Description :
quirksmode.org en donne une bonne description. En résumé (copié de quirksmode) :
Capture d'événements
Lorsque vous utilisez la capture d'événements
| | ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 \ / | | | ------------------------- | | Event CAPTURING | -----------------------------------
le gestionnaire d'événements de l'élément 1 se déclenche en premier, le gestionnaire d'événements de l'élément 2 se déclenche en dernier.
Bulles d'événements
Lorsque vous utilisez le bouillonnement d'événements
/ \ ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 | | | | | ------------------------- | | Event BUBBLING | -----------------------------------
le gestionnaire d'événements de l'élément 2 se déclenche en premier, le gestionnaire d'événements de l'élément 1 se déclenche en dernier.
Que faut-il utiliser ?
Cela dépend de ce que vous voulez faire. Il n'y a pas de meilleure solution. La différence réside dans l'ordre d'exécution des gestionnaires d'événements. La plupart du temps, il est préférable d'exécuter les gestionnaires d'événements dans l'ordre suivant bouillonnant mais il peut aussi être nécessaire de les licencier plus tôt.
Les deux ne se produisent-ils pas, d'abord la capture et ensuite le bouillonnement, aussi qu'est-ce que l'événement de répartition ?
S'il y a deux éléments, l'élément 1 et l'élément 2. L'élément 2 est à l'intérieur de l'élément 1 et nous attachons un gestionnaire d'événement aux deux éléments, disons onClick. Maintenant, lorsque nous cliquons sur l'élément 2, le gestionnaire d'événement des deux éléments sera exécuté. Maintenant, la question est de savoir dans quel ordre l'événement sera exécuté. Si l'événement attaché à l'élément 1 s'exécute en premier, on parle de capture d'événement et si l'événement attaché à l'élément 2 s'exécute en premier, on parle de bouillonnement d'événement. Selon le W3C, l'événement commence dans la phase de capture jusqu'à ce qu'il atteigne la cible et revienne à l'élément, puis il commence à bouillonner.
Les états de capture et de bouillonnement sont connus par le paramètre useCapture de la méthode addEventListener
eventTarget.addEventListener(type,listener,[,useCapture]) ;
Par défaut, useCapture est faux. Cela signifie qu'il est en phase de bouillonnement.
var div1 = document.querySelector("#div1");
var div2 = document.querySelector("#div2");
div1.addEventListener("click", function (event) {
alert("you clicked on div 1");
}, true);
div2.addEventListener("click", function (event) {
alert("you clicked on div 2");
}, false);
#div1{
background-color:red;
padding: 24px;
}
#div2{
background-color:green;
}
<div id="div1">
div 1
<div id="div2">
div 2
</div>
</div>
Essayez de changer le vrai et le faux.
@masterxilo : pas besoin de Fiddle, StackOverflow supporte maintenant code en ligne (extraits de pile) .
Concernant the event will start in the capturing phase untill it reaches the target comes back to the element and then it starts bubbling
. Je n'ai trouvé que le addEventListener a le paramètre useCapture
qui peut être défini comme vrai ou faux ; et en HTML 4.0, les écouteurs d'événements étaient spécifiés comme attributs d'un élément y useCapture defaults to false
. Pourriez-vous indiquer un lien vers une spécification qui confirme ce que vous avez écrit ?
J'ai trouvé ceci tutoriel à javascript.info pour être très clair dans l'explication de ce sujet. Et son résumé en 3 points à la fin parle vraiment des points cruciaux. Je le cite ici :
- Les événements sont d'abord capturés jusqu'à la cible la plus profonde, puis remontés. Dans IE<9, ils ne font que buller.
- Tous les manipulateurs travaillent sur l'étape de bouillonnement sauf
addEventListener
avec le dernier argumenttrue
qui est le seul moyen de d'assister à l'événement en capturant la scène.- Le bullage/captage peut être arrêté par
event.cancelBubble=true
(IE) ouevent.stopPropagation()
pour les autres navigateurs.
Il y a aussi le Event.eventPhase
qui permet de savoir si l'événement se situe au niveau de la cible ou s'il provient d'un autre endroit, et elle est entièrement prise en charge par les navigateurs.
En développant le programme déjà excellent extrait de la réponse acceptée Voici le résultat obtenu en utilisant la méthode eventPhase
propriété
var logElement = document.getElementById('log');
function log(msg) {
if (logElement.innerHTML == "<p>No logs</p>")
logElement.innerHTML = "";
logElement.innerHTML += ('<p>' + msg + '</p>');
}
function humanizeEvent(eventPhase){
switch(eventPhase){
case 1: //Event.CAPTURING_PHASE
return "Event is being propagated through the target's ancestor objects";
case 2: //Event.AT_TARGET
return "The event has arrived at the event's target";
case 3: //Event.BUBBLING_PHASE
return "The event is propagating back up through the target's ancestors in reverse order";
}
}
function capture(e) {
log('capture: ' + this.firstChild.nodeValue.trim() + "; " +
humanizeEvent(e.eventPhase));
}
function bubble(e) {
log('bubble: ' + this.firstChild.nodeValue.trim() + "; " +
humanizeEvent(e.eventPhase));
}
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', capture, true);
divs[i].addEventListener('click', bubble, false);
}
p {
line-height: 0;
}
div {
display:inline-block;
padding: 5px;
background: #fff;
border: 1px solid #aaa;
cursor: pointer;
}
div:hover {
border: 1px solid #faa;
background: #fdd;
}
<div>1
<div>2
<div>3
<div>4
<div>5</div>
</div>
</div>
</div>
</div>
<button onclick="document.getElementById('log').innerHTML = '<p>No logs</p>';">Clear logs</button>
<section id="log"></section>
Document connexe de MDN sur composedPath
et la limite d'ombre d'un élément DOM, est un contexte supplémentaire important.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
3 votes
Je vous recommande ce lien utile : javascript.info/bubbling-and-capturing
0 votes
@CommunityAns : ce site est excellent, mais ce sujet, en particulier, est décrit de manière un peu confuse.