Je me suis demandé si event.preventDefault()
et return false
Étaient les mêmes.
J'ai fait quelques tests , et il semble que
Si le gestionnaire d'événements est ajouté à l'aide de l'ancien modèle, par exemple
elem.onclick = function(){
return false;
};
Ensuite, return false
Empêche les actions par défaut, comme event.preventDefault()
.
Si le gestionnaire d'événements est ajouté à l'aide de addEventListener
, par exemple
elem.addEventListener(
'click',
function(e){
return false;
},
false
);
Ensuite, return false
N'empêche pas l'action par défaut.
Est-ce que tous les navigateurs se comportent comme ça?
Existe-t-il plus de différences entre event.preventDefault()
et return false
?
Où puis-je trouver de la documentation (je ne pouvais pas dans MDN) sur le comportement de return false
Comme event.preventDefault()
dans certains cas?
Ma question ne concerne que le javascript, pas jQuery. Ne la marquez donc pas comme un doublon de event.preventDefault () vs. return false , même si les deux questions ont presque le même titre.
Le Spécification d'événements de modèle d'objet de document du W3C dans 1.3.1. Interfaces d’enregistrement d’événements indique que handleEvent
dans EventListener n’a aucune valeur de retour:
handleEvent
Cette méthode est appelée chaque fois qu'un événement du type pour lequel l'interface EventListener a été enregistrée se produit. [...] Aucune valeur de retour
sous 1.2.4. Annulation d'événement le document indique également que
L'annulation est accomplie en appelant la méthode preventDefault de l'événement. Si un ou plusieurs EventListeners appellent preventDefault au cours d'une phase du flux d'événements, l'action par défaut sera annulée.
ce qui devrait vous décourager d’utiliser tout effet que renvoyer true/false dans un navigateur et utiliser event.preventDefault()
.
Mettre à jour
La spécification HTML5 spécifie en fait comment traiter une valeur de retour différente. Section 7.1.5.1 de la spécification HTML indique que
Si la valeur renvoyée est une valeur fausse booléenne WebIDL, annulez l'événement.
pour tout sauf l'événement "mouseover".
Conclusion
Je recommanderais toujours d'utiliser event.preventDefault()
dans la plupart des projets, car vous serez compatible avec les anciennes spécifications et donc avec les anciens navigateurs. Si vous ne devez prendre en charge que la coupe des navigateurs Edge, renvoyer false pour annuler est acceptable.
Voici quelques exemples qui pourraient aider les gens à comprendre et à mieux résoudre leurs problèmes.
onclick
directement dans le balisage html ou via setAttribute('onclick'...)
a ses propres pièges pour ce qui est de s'assurer que vous retournez réellement car le contenu de onclick=
est encapsulé dans un onclick
fonction.onclick
, vous pouvez annuler l'événement en vous assurant que la fonction onclick
renvoie false ... votre fonction est encapsulée ... vous devez donc exécuter onclick="return myHandler();"
ou onclick="myHandler(); return false;"
ou quelque chose comme ça pour s'assurer que onclick retourne false.getEventListeners
pour voir à quoi ressemble votre écouteur d'événement, et vérifier si votre gestionnaire d'événement ne se comporte pas comme prévu.Cet exemple est spécifique à l'événement click
avec un lien <a>
... mais peut être généralisé pour la plupart des types d'événements.
Nous avons une ancre (lien) avec la classe js-some-link-hook
Que nous voulons ouvrir une modale et empêcher toute navigation dans les pages.
Les exemples ci-dessous ont été exécutés dans Google chrome (71) sur MacOS Mojave.
Un écueil majeur est de supposer que onclick=functionName
A le même comportement que d'utiliser addEventListener
function eventHandler (event) {
// want to prevent link navigation
alert('eventHandler ran');
return false;
}
function addEventListenerToElement () {
var link = document.querySelector('.js-some-link-hook');
link.setAttribute('onclick', eventHandler);
}
addEventListenerToElement();
Puis exécutez dans la console devtools du navigateur:
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener); // to avoid truncation of output
... et vous voyez:
function onclick(event) {
function t(n){return alert("eventHandler ran"),!1}
}
Cela ne marche pas du tout. Lorsque vous utilisez onclick=
, Votre fonction de gestionnaire est encapsulée dans une autre fonction. Dans ce cas, vous pouvez voir que ma définition de fonction est incluse mais non appelée car j'ai spécifié la référence de la fonction sans l'invoquer. De plus, vous pouvez voir que même si ma fonction était invoquée et que ma fonction renvoyait false ... la fonction onclick ne renverrait pas cette valeur false ... qui est nécessaire pour "annuler" l'événement. Nous avons vraiment besoin que return myHandlerFunc();
soit intégré à la fonction onclick pour que tout fonctionne.
Maintenant que nous voyons comment cela fonctionne, nous pouvons modifier le code pour faire ce que nous voulons. Exemple impair à des fins d'illustration (n'utilisez pas ce code):
function eventHandler (event) {
// want to prevent link navigation
alert('eventHandler ran');
return false;
}
function addEventListenerToElement () {
var link = document.querySelector('.js-some-link-hook');
link.setAttribute('onclick', 'return ('+eventHandler+')();');
}
addEventListenerToElement();
Vous voyez que nous avons encapsulé notre définition de fonction eventHandler dans une chaîne. Plus précisément: une fonction à exécution automatique avec une déclaration return au début.
Encore une fois dans chrome console devtools:
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener); // to avoid truncation of output
...montre:
function onclick(event) {
return (function t(e){return alert("eventHandler ran"),!1})();
}
... alors oui, ça devrait marcher. Notre return false
(!1
En raison de la minification en cours, désolé). En effet, si nous cliquons sur le lien, nous obtenons l'alerte et, si elle est ignorée, la page ne navigue ni ne s'actualise.
function eventHandler (event) {
// want to prevent link navigation
alert('eventHandler ran');
return false;
}
function addEventListenerToElement () {
var link = document.querySelector('.js-some-link-hook');
link.addEventListener('click', eventHandler, false);
}
addEventListenerToElement();
navigateur devtools:
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener); // to avoid truncation of output
résultat:
function e(n){return alert("eventHandler ran"),!1}
Donc, vous pouvez déjà voir la différence. Nous ne sommes pas enveloppés dans une fonction onclick. Ainsi, notre return false
(return !1
En raison d'une minification) se situe au plus haut niveau ici et nous n'avons pas à nous inquiéter d'ajouter une déclaration de retour supplémentaire comme avant.
Donc, il semble que cela devrait fonctionner. En cliquant sur le lien, nous recevons l'alerte. Annulez l'alerte et la page navigue/est actualisée. C'est-à-dire que l'événement n'a PAS été annulé en renvoyant false.
Si nous recherchons la spécification (voir les ressources en bas), nous constatons que notre fonction callback/handler pour addEventListener ne prend pas en charge le type de retour. Nous pouvons retourner ce que nous voulons, mais comme cela ne fait pas partie de l'interface, cela n'a aucun effet.
Solution: utiliser event.preventDefault()
au lieu de return false;
...
function eventHandler (event) {
// want to prevent link navigation
event.preventDefault();
alert('eventHandler ran');
}
function addEventListenerToElement () {
var link = document.querySelector('.js-some-link-hook');
link.addEventListener('click', eventHandler, false);
}
addEventListenerToElement();
navigateur devtools ...
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener); // to avoid truncation of output
donne ...
function n(e){e.preventDefault(),alert("eventHandler ran")}
...comme prévu.
Test: recevez l'alerte. Rejeter l'alerte. Non la navigation de la page ou actualiser ... qui est ce que nous voulons.
La spécification html5 ( https://www.w3.org/TR/html5/webappapis.html#events ) confond les choses car elle utilise à la fois onclick
et addEventListener
dans leurs exemples et ils disent ce qui suit:
L'algorithme de traitement du gestionnaire d'événements pour un gestionnaire d'événements H et un objet d'événement E est le suivant:
...
- Traiter la valeur de retour comme suit:
...
Si la valeur renvoyée est une valeur fausse booléenne Web IDL, annulez l'événement.
Cela semble donc impliquer que return false
Annule l'événement pour addEventListener
et onclick
.
Mais si vous regardez leur définition liée de event-handler
, Vous voyez:
Un gestionnaire d'événements a un nom, qui commence toujours par "on" et est suivi du nom de l'événement auquel il est destiné.
...
Les gestionnaires d’événements sont exposés de deux manières.
La première méthode, commune à tous les gestionnaires d’événements, consiste en un attribut IDL de gestionnaire d’événements.
La deuxième façon est comme un attribut de contenu de gestionnaire d'événement. Les gestionnaires d'événements sur les éléments HTML et certains des gestionnaires d'événements sur les objets Windows sont exposés de cette manière.
https://www.w3.org/TR/html5/webappapis.html#event-handler
Il semble donc que l'annulation de l'événement par return false
Ne s'applique réellement qu'aux gestionnaires d'événements onclick
(ou généralement on*
) Et non aux gestionnaires d'événements enregistrés via addEventListener
qui a une API différente. Étant donné que l'API addEventListener n'est pas couverte par la spécification html5 et que seuls les gestionnaires d'événements on*
... il serait moins déroutant de s'y tenir dans leurs exemples et d'appeler spécifiquement la différence.