web-dev-qa-db-fra.com

Quelle est la différence entre event.stopPropagation et event.preventDefault?

Ils semblent faire la même chose ... Est-ce qu'un moderne et un vieux? Ou sont-ils pris en charge par différents navigateurs?

Lorsque je gère moi-même les événements (sans cadre), je vérifie toujours les deux et les exécute s'ils sont présents. (J'ai aussi return false, mais j'ai le sentiment que cela ne fonctionne pas avec les événements attachés avec node.addEventListener).

Alors pourquoi les deux? Devrais-je continuer à vérifier les deux? Ou y a-t-il réellement une différence?

(Je sais, beaucoup de questions, mais ce sont toutes les mêmes =))

651
Rudie

stopPropagation empêche l'événement de remonter dans la chaîne d'événements.

preventDefault empêche l'action par défaut que le navigateur effectue sur cet événement.

Disons que vous avez

<div id="foo">
 <button id="but" />
</div>

$("#foo").click(function() {
   // mouse click on div
});

$("#but").click(function(ev) {
   // mouse click on button
   ev.stopPropagation();
});

Exemple

$("#but").click(function(event){
  event.preventDefault();
 });


$("#foo").click(function(){
 alert("parent click event fired !");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
  <button id="but">button</button>
</div>

$("#but").click(function(event){
  event.stopPropagation();
 });


$("#foo").click(function(){
 alert("parent click event fired !");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
  <button id="but">button</button>
</div>

Avec stopPropagation, seul le gestionnaire de clics boutons est appelé et le gestionnaire de clics divs ne se déclenche jamais.

Où comme si vous veniez preventDefault, seule l'action par défaut du navigateur est arrêtée mais le gestionnaire de clics de la div est toujours activé.

Vous trouverez ci-dessous une documentation sur les objets d'événement DOM de MDN et MSDN.

MDN:

Pour IE9 et FF, vous pouvez simplement utiliser preventDefault & stopPropagation.

Pour prendre en charge IE8 et versions antérieures, remplacez stopPropagation par cancelBubble et remplacez preventDefault par returnValue

849
Raynos

Terminologie

De quirksmode.org :

Capture d'événement

Lorsque vous utilisez la capture d'événement

 | | 
--------------- | | -----------------
 | element1 | | | 
 | ----------- | | ----------- | 
 | | element2 \/| | 
 | ------------------------- | 
 | CAPTURATION d'événement | 
 ----------------------------------- 

le gestionnaire d'événements de element1 est déclenché en premier, le gestionnaire d'événements de element2 en dernier.

Bouillonnement d'événement

Lorsque vous utilisez un événement bouillonnant

/\ 
--------------- | | -----------------
 | element1 | | | 
 | ----------- | | ----------- | 
 | | element2 | | | | 
 | ------------------------- | 
 | Événement BUBBLING | 
 ----------------------------------- 

le gestionnaire d'événements de element2 est déclenché en premier, le gestionnaire d'événements de element1 en dernier.

Tout événement se produisant dans le modèle d'événement du W3C est d'abord capturé jusqu'à ce qu'il atteigne l'élément cible, puis remonte à nouveau.

 | |/\ 
----------------- | | - | | -----------------
 | element1 | | | | | 
 | ------------- | | - | | ----------- | 
 | | element2 \/| | | | 
 | -------------------------------- | 
 | Modèle d'événement du W3C | 
----------------------------------------------

Interface

De w3.org , pour capture d’événement:

Si la capture EventListener souhaite empêcher le traitement ultérieur de Si l'événement se produit, il peut appeler la méthode stopPropagation du fichier Event interface. Cela empêchera l'envoi ultérieur de l'événement, bien que EventListeners supplémentaire soit enregistré dans la même hiérarchie niveau recevra toujours l'événement. Une fois l'événement stopPropagation méthode a été appelée, les appels ultérieurs à cette méthode n'ont pas effet supplémentaire. S'il n'y a pas de capteurs supplémentaires et que stopPropagation n'a pas été appelé, l'événement déclenche le EventListeners approprié sur la cible elle-même.

Pour event bubbling:

Tout gestionnaire d’événements peut choisir d’empêcher la propagation de l’événement par appel de la méthode stopPropagation de l'interface Event. Si seulement EventListener appelle cette méthode, tous les EventListeners supplémentaires sur le fichier EventTarget actuel sera déclenché mais le bouillonnement cessera à ce moment niveau. Un seul appel à stopPropagation est requis pour empêcher la poursuite de bouillonnant.

Pour annulation d'événement:

L’annulation est accomplie en appelant le Event.__ de preventDefault. méthode. Si un ou plusieurs EventListeners appelez preventDefault pendant quelle que soit la phase du flux d’événements, l’action par défaut sera annulée.

Exemples

Dans les exemples suivants, un clic sur le lien hypertexte dans le navigateur Web déclenche le flux de l'événement (les écouteurs d'événements sont exécutés) et l'action par défaut de la cible de l'événement (un nouvel onglet est ouvert).

HTML:

<div id="a">
  <a id="b" href="http://www.google.com/" target="_blank">Google</a>
</div>
<p id="c"></p>

JavaScript:

var el = document.getElementById("c");

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
}

function capturingOnClick2(ev) {
    el.innerHTML += "A event capture<br>";
}

function bubblingOnClick1(ev) {
    el.innerHTML += "DIV event bubbling<br>";
}

function bubblingOnClick2(ev) {
    el.innerHTML += "A event bubbling<br>";
}

// The 3rd parameter useCapture makes the event listener capturing (false by default)
document.getElementById("a").addEventListener("click", capturingOnClick1, true);
document.getElementById("b").addEventListener("click", capturingOnClick2, true);
document.getElementById("a").addEventListener("click", bubblingOnClick1, false);
document.getElementById("b").addEventListener("click", bubblingOnClick2, false);

Exemple 1 : il en résulte la sortie

DIV event capture
A event capture
A event bubbling
DIV event bubbling

Exemple 2 : ajout de stopPropagation() à la fonction

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
    ev.stopPropagation();
}

résultats dans la sortie

DIV event capture

L'auditeur d'événement a empêché la propagation ultérieure de l'événement vers le bas et vers le haut. Cependant, cela n’empêche pas l’action par défaut (une nouvelle ouverture de l’onglet).

Exemple 3 : ajout de stopPropagation() à la fonction

function capturingOnClick2(ev) {
    el.innerHTML += "A event capture<br>";
    ev.stopPropagation();
}

ou la fonction

function bubblingOnClick2(ev) {
    el.innerHTML += "A event bubbling<br>";
    ev.stopPropagation();
}

résultats dans la sortie

DIV event capture
A event capture
A event bubbling

En effet, les deux écouteurs d'événement sont enregistrés sur la même cible d'événement. Les écouteurs d'événement ont empêché toute propagation ultérieure de l'événement. Cependant, ils n’ont pas empêché l’action par défaut (une nouvelle ouverture d’onglet).

Exemple 4 : ajout de preventDefault() à une fonction, par exemple

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
    ev.preventDefault();
}

empêche un nouvel onglet de s'ouvrir.

197
Ashkan

retourne faux;


return false; fait 3 choses différentes quand vous l'appelez:

  1. event.preventDefault() - Il arrête le comportement par défaut des navigateurs.
  2. event.stopPropagation() - Il empêche l’événement de propager (ou de «remonter») le DOM.
  3. Arrête l'exécution du rappel et retourne immédiatement lorsqu'il est appelé.

Notez que ce comportement diffère des gestionnaires d'événements normaux (non jQuery), dans lesquels, notamment, return false n'empêche pas la propagation de l'événement.

preventDefault ();


preventDefault(); fait une chose: il arrête le comportement par défaut des navigateurs.

Quand les utiliser?


Nous savons ce qu'ils font mais quand les utiliser? Cela dépend simplement de ce que vous voulez accomplir. Utilisez preventDefault(); si vous souhaitez "simplement" empêcher le comportement du navigateur par défaut. Utilisez return false; lorsque vous souhaitez empêcher le comportement du navigateur par défaut et empêcher l’événement de propager le DOM. Dans la plupart des cas, vous utiliseriez return false; ce que vous voulez vraiment, c'est preventDefault().

Exemples:


Essayons de comprendre avec des exemples:

Nous allons voir exemple pur JAVASCRIPT

Exemple 1:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    alert('Link Clicked');
  }

  function executeParent() {
    alert('div Clicked');
  }
</script>

Exécutez le code ci-dessus, vous verrez le lien hypertexte ‘Cliquez ici pour visiter stackoverflow.com 'maintenant, si vous cliquez d'abord sur ce lien, vous obtiendrez l'alerte javascript Lien cliqué Ensuite, vous obtiendrez le javascript alert div Cliquez sur et vous serez immédiatement redirigé vers stackoverflow.com.

Exemple 2:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.preventDefault();
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
  }

  function executeParent() {
    alert('div Clicked');
  }
</script>

Exécutez le code ci-dessus, vous verrez le lien hypertexte ‘Cliquez ici pour visiter stackoverflow.com ‘Maintenant, si vous cliquez sur ce lien d’abord, vous obtiendrez l'alerte javascript Lien cliqué Ensuite, vous obtiendrez le javascript alert div Clicked Ensuite, vous verrez le lien hypertexte ‘Cliquez ici pour visiter stackoverflow.com "remplacé par le texte" événement de clic empêché " et vous non serez redirigé vers stackoverflow.com. Ceci est dû à la méthode event.preventDefault () que nous avons utilisée pour empêcher le clic par défaut action à déclencher.

Exemple 3:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.stopPropagation();
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
  }

  function executeParent() {
    alert('div Clicked');
  }
</script>

Cette fois si vous cliquez sur Lier, la fonction executeParent () ne sera pas être appelé et vous ne recevrez pas l'alerte javascript div Clicked cette fois. Cela est dû au fait que nous avons empêché la propagation au parent div utilisant la méthode event.stopPropagation (). Ensuite, vous verrez le lien hypertexte "Cliquez ici pour visiter stackoverflow.com" remplacé par le texte "L’événement click va être exécuté" et vous le serez immédiatement redirigé vers stackoverflow.com. C’est parce que nous n’avons pas empêché l'action de clic par défaut de déclencher cette fois en utilisant Méthode event.preventDefault ().

Exemple 4:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.preventDefault();
    event.stopPropagation();
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
  }

  function executeParent() {
    alert('Div Clicked');
  }
</script>

Si vous cliquez sur le lien, la fonction executeParent () ne sera pas appelé et vous ne recevrez pas l’alerte javascript. Cela nous est dû avoir empêché la propagation à la div parente en utilisant Méthode event.stopPropagation (). Ensuite, vous verrez le lien hypertexte ‘Cliquez sur cliquez ici pour visiter stackoverflow.com "remplacé par le texte" Click event empêché "et vous ne serez pas redirigé vers stackoverflow.com. Ce C’est parce que nous avons empêché l’action de clic par défaut de déclencher cette fois en utilisant la méthode event.preventDefault ().

Exemple 5:

Pour le retour faux, j'ai trois exemples et tous semblent faire exactement la même chose (tout en retournant faux), mais en réalité le les résultats sont assez différents. Voici ce qui se passe réellement dans chacun de ce qui précède.

cas:

  1. Renvoyer false à partir d'un gestionnaire d'événements en ligne empêche le navigateur d'accéder à l'adresse du lien, mais n'empêche pas l'événement de se propager via le DOM.
  2. Renvoyer false à partir d'un gestionnaire d'événements jQuery empêche le navigateur de naviguer vers l'adresse du lien et empêche l'événement de se propager via le DOM.
  3. Renvoyer false à partir d'un gestionnaire d'événements DOM normal ne fait absolument rien.

Va voir tous les trois exemple.

  1. Retour en ligne faux.

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='return false'>Click here to visit stackoverflow.com</a>
</div>
<script>
  var link = document.querySelector('a');

  link.addEventListener('click', function() {
    event.currentTarget.innerHTML = 'Click event prevented using inline html'
    alert('Link Clicked');
  });


  function executeParent() {
    alert('Div Clicked');
  }
</script>

  1. Renvoi false à partir d'un gestionnaire d'événements jQuery.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <a href='https://stackoverflow.com'>Click here to visit stackoverflow.com</a>
</div>
<script>
  $('a').click(function(event) {
    alert('Link Clicked');
    $('a').text('Click event prevented using return FALSE');
    $('a').contents().unwrap();
    return false;
  });
  $('div').click(function(event) {
    alert('Div clicked');
  });
</script>

  1. Renvoyer false à partir d'un gestionnaire d'événements DOM normal.

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
    return false
  }

  function executeParent() {
    alert('Div Clicked');
  }
</script>

J'espère que ces exemples sont clairs. Essayez d’exécuter tous ces exemples dans un fichier html pour voir comment ils fonctionnent.

51
Keval Bhatt

Voici la citation de ici

Event.preventDefault

La méthode preventDefault empêche un événement d’exécuter ses fonctionnalités par défaut. Par exemple, vous utiliseriez preventDefault sur un élément A pour cesser de cliquer sur cet élément en quittant la page en cours:

//clicking the link will *not* allow the user to leave the page 
myChildElement.onclick = function(e) { 
    e.preventDefault(); 
    console.log('brick me!'); 
};

//clicking the parent node will run the following console statement because event propagation occurs
logo.parentNode.onclick = function(e) { 
    console.log('you bricked my child!'); 
};

Alors que la fonctionnalité par défaut de l'élément est configurée en brique, l'événement continue à faire bouillonner le DOM.

Event.stopPropagation

La deuxième méthode, stopPropagation, permet à la fonctionnalité par défaut de l'événement de se produire mais empêche sa propagation:

//clicking the element will allow the default action to occur but propagation will be stopped...
myChildElement.onclick = function(e) { 
    e.stopPropagation();
    console.log('prop stop! no bubbles!'); 
};

//since propagation was stopped by the child element's onClick, this message will never be seen!
myChildElement.parentNode.onclick = function(e) { 
    console.log('you will never see this message!'); 
};

stopPropagation empêche efficacement les éléments parents de connaître un événement donné sur son enfant. 

Bien qu'une simple méthode d'arrêt nous permette de gérer rapidement les événements, c'est important de penser à ce que vous voulez exactement avec bouillonnant. Je parierais que tout ce qu'un développeur veut vraiment, c'est preventDefault 90% du temps! "Arrêter" de manière incorrecte un événement pourrait vous causer nombreux problèmes sur la ligne; vos plugins peuvent ne pas fonctionner et votre les plugins tiers pourraient être maquillés. Ou pire encore - votre code casse d'autres fonctionnalités sur un site.

15
VladL

e.preventDefault () empêchera que l'événement par défaut ne se produise, e.stopPropagation () empêchera l'événement de se propager et renverra false fera les deux. 

event.stopPropagation () permet à d'autres gestionnaires du même élément d'être exécutés, alors que event.stopImmediatePropagation () empêche l'exécution de tous les événements.

1
Raghava

Event.preventDefault- arrête le comportement par défaut du navigateur. Vient maintenant quel est le comportement par défaut du navigateur. Supposons que vous avez une balise anchor et qu'elle possède un attribut href et que cette balise ancre est imbriquée dans une balise div qui comporte un événement click. Le comportement par défaut de la balise d'ancrage est que lorsque vous cliquez dessus, elle doit naviguer, mais event.preventDefault arrête la navigation dans ce cas. Mais cela n'arrête jamais le bouillonnement d'événement ou l'escalade d'événement i.e

<div class="container">
 <a href="#" class="element">Click Me!</a>
</div>

$('.container').on('click', function(e) {
 console.log('container was clicked');
});

$('.element').on('click', function(e) {
  e.preventDefault(); // Now link won't go anywhere
  console.log('element was clicked');
});

Le résultat sera 

"l'élément a été cliqué"

"le conteneur a été cliqué"

Maintenant, event.StopPropation arrête la diffusion de l'événement ou son escalade. Maintenant avec l'exemple ci-dessus 

$('.container').on('click', function(e) {
  console.log('container was clicked');
});

$('.element').on('click', function(e) {
  e.preventDefault(); // Now link won't go anywhere
  e.stopPropagation(); // Now the event won't bubble up
 console.log('element was clicked');
});

Le résultat sera 

"l'élément a été cliqué"

Pour plus d'informations, consultez ce lien https://codeplanet.io/preventdefault-vs-stoppropagation-vs-stopimmediatepropagation/

0
Nayas Subramanian

event.preventDefault(); Arrête l'action par défaut d'un élément.

event.stopPropagation(); Empêche l’événement de remonter dans l’arborescence DOM, empêchant ainsi les gestionnaires parents d’être avertis de cet événement.

Par exemple, si un lien avec une méthode de clic est attaché à l'intérieur d'une DIV ou FORM qui a également une méthode de clic attachée, cela empêchera le déclenchement de la méthode de clic DIV ou FORM.

0
Mike Clark