Les deux sont corrects, mais aucun d'entre eux n'est "meilleur" en soi, et il peut y avoir une raison pour laquelle le développeur a choisi d'utiliser les deux approches.
Écouteurs d'événements (addEventListener et attachEvent d'IE)
Les versions antérieures d'Internet Explorer implémentent javascript différemment de pratiquement tous les autres navigateurs. Avec les versions inférieures à 9, vous utilisez la méthode attachEvent
[ doc ], comme ceci:
element.attachEvent('onclick', function() { /* do stuff here*/ });
Dans la plupart des autres navigateurs (y compris IE 9 et supérieur), vous utilisez addEventListener
[ doc ], comme ceci:
element.addEventListener('click', function() { /* do stuff here*/ }, false);
En utilisant cette approche ( événements DOM niveau 2 ), vous pouvez attacher un nombre théoriquement illimité d'événements à un seul élément. La seule limitation pratique est la mémoire côté client et d'autres problèmes de performances, qui sont différents pour chaque navigateur.
Les exemples ci-dessus représentent l'utilisation d'une fonction anonyme [ doc ]. Vous pouvez également ajouter un écouteur d'événements à l'aide d'une référence de fonction [ doc ] ou d'une fermeture [ doc ]:
var myFunctionReference = function() { /* do stuff here*/ }
element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);
Une autre caractéristique importante de addEventListener
est le paramètre final, qui contrôle la façon dont l'auditeur réagit aux événements de propagation [ doc ]. Je suis passé faux dans les exemples, ce qui est standard pour probablement 95% des cas d'utilisation. Il n'y a pas d'argument équivalent pour attachEvent
ou lors de l'utilisation d'événements en ligne.
Événements en ligne (propriété HTML onclick = "" et element.onclick)
Dans tous les navigateurs qui prennent en charge javascript, vous pouvez mettre un écouteur d'événements en ligne, ce qui signifie directement dans le code HTML. Vous l'avez probablement vu:
<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>
La plupart des développeurs expérimentés évitent cette méthode, mais elle fait le travail; c'est simple et direct. Vous ne pouvez pas utiliser de fermetures ou de fonctions anonymes ici (bien que le gestionnaire lui-même soit en quelque sorte une fonction anonyme), et votre contrôle de la portée est limité.
L'autre méthode que vous mentionnez:
element.onclick = function () { /*do stuff here */ };
... est l'équivalent du javascript en ligne, sauf que vous avez plus de contrôle sur la portée (puisque vous écrivez un script plutôt que HTML) et pouvez utiliser des fonctions anonymes, des références de fonction et / ou des fermetures.
L'inconvénient majeur des événements en ligne est que, contrairement aux écouteurs d'événements décrits ci-dessus, vous ne pouvez affecter qu'un seul événement en ligne. Les événements en ligne sont stockés en tant qu'attribut / propriété de l'élément [ doc ], ce qui signifie qu'il peut être remplacé.
En utilisant l'exemple <a>
du HTML ci-dessus:
var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };
... lorsque vous avez cliqué sur l'élément, vous ne voyez que "Did stuff # 2" - vous avez remplacé la première affectée de la onclick
propriété par la deuxième valeur, et vous avez également remplacé la onclick
propriété HTML inline d'origine . Découvrez-le ici: http://jsfiddle.net/jpgah/ .
D'une manière générale, n'utilisez pas d'événements en ligne . Il peut y avoir des cas d'utilisation spécifiques pour cela, mais si vous n'êtes pas sûr à 100% que vous avez ce cas d'utilisation, alors vous ne devez pas et ne devez pas utiliser d'événements en ligne.
Javascript moderne (angulaire et similaire)
Depuis que cette réponse a été publiée à l'origine, les frameworks javascript comme Angular sont devenus beaucoup plus populaires. Vous verrez du code comme celui-ci dans un modèle angulaire:
<button (click)="doSomething()">Do Something</button>
Cela ressemble à un événement en ligne, mais ce n'est pas le cas. Ce type de modèle sera transposé en code plus complexe qui utilise des écouteurs d'événements en coulisses. Tout ce que j'ai écrit sur les événements ici s'applique toujours, mais vous êtes retiré de la réalité par au moins une couche. Vous devez comprendre les règles de base, mais si les meilleures pratiques de votre framework JS moderne impliquent l'écriture de ce type de code dans un modèle, ne vous sentez pas comme si vous utilisiez un événement en ligne - vous ne l'êtes pas.
Quel est le meilleur?
La question est une question de compatibilité et de nécessité du navigateur. Avez-vous besoin d'attacher plus d'un événement à un élément? Le ferez-vous à l'avenir? Les chances sont, vous le ferez. attachEvent et addEventListener sont nécessaires. Sinon, un événement en ligne peut sembler faire l'affaire, mais vous êtes bien mieux servi à préparer un avenir qui, bien que cela puisse sembler improbable, est au moins prévisible. Il est possible que vous deviez passer à des écouteurs d'événements basés sur JS, vous pouvez donc tout aussi bien commencer par là. N'utilisez pas d'événements en ligne.
jQuery et d'autres frameworks javascript encapsulent les différentes implémentations de navigateur des événements DOM niveau 2 dans des modèles génériques afin que vous puissiez écrire du code compatible avec plusieurs navigateurs sans avoir à vous soucier de l'historique d'IE en tant que rebelle. Même code avec jQuery, tous cross-browser et prêt à basculer:
$(element).on('click', function () { /* do stuff */ });
Ne manquez pas et n'obtenez pas un cadre juste pour cette seule chose, cependant. Vous pouvez facilement lancer votre propre petit utilitaire pour prendre soin des anciens navigateurs:
function addEvent(element, evnt, funct){
if (element.attachEvent)
return element.attachEvent('on'+evnt, funct);
else
return element.addEventListener(evnt, funct, false);
}
// example
addEvent(
document.getElementById('myElement'),
'click',
function () { alert('hi!'); }
);
Essayez-le: http://jsfiddle.net/bmArj/
En tenant compte de tout cela, à moins que le script que vous regardez ne prenne en compte les différences de navigateur d'une autre manière (dans le code non affiché dans votre question), la partie utilisant addEventListener
ne fonctionnerait pas dans les versions IE inférieures à 9.
Documentation et lectures connexes
function addEvent(element, myEvent, fnc) { return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false)); }
function addEvent(e,n,f){return e.attachEvent?e.attachEvent('on'+n,f):e.addEventListener(n,f,!!0)}
<< À 98 caractères, celui-ci est plus de 40% plus petit!La différence que vous pourriez voir si vous aviez un autre couple de fonctions:
Les fonctions 2, 3 et 4 fonctionnent, mais pas 1. En effet,
addEventListener
n'écrase pas les gestionnaires d'événements existants, alors qu'ilonclick
remplace tous lesonclick = fn
gestionnaires d'événements existants .L'autre différence significative, bien sûr, est que
onclick
cela fonctionnera toujours, alorsaddEventListener
qu'il ne fonctionne pas dans Internet Explorer avant la version 9. Vous pouvez utiliser l'analogueattachEvent
(qui a une syntaxe légèrement différente) dans IE <9.la source
Dans cette réponse, je décrirai les trois méthodes de définition des gestionnaires d'événements DOM.
element.addEventListener()
Exemple de code:
Afficher l'extrait de code
element.addEventListener()
présente de multiples avantages:element.removeEventListener()
.useCapture
paramètre, qui indique si vous souhaitez gérer l'événement dans sa phase de capture ou de propagation . Voir: Impossible de comprendre l'attribut useCapture dans addEventListener ..onevent
propriétés des éléments DOM, de nombreux programmeurs JavaScript inexpérimentés pensent que le nom de l'événement est par exempleonclick
ouonload
. neon
fait pas partie du nom de l'événement . Les noms d'événement corrects sontclick
etload
, et c'est ainsi que les noms d'événement sont transmis.addEventListener()
.element.onevent = function() {}
(par exempleonclick
,onload
)Exemple de code:
Afficher l'extrait de code
C'était un moyen d'enregistrer les gestionnaires d'événements dans DOM 0. C'est maintenant déconseillé, car il:
onevent
propriété à son état initial (c'est-à-direnull
).window.onload
, par exemple:,window.onload = "test";
il ne générera aucune erreur. Votre code ne fonctionnerait pas et il serait vraiment difficile de savoir pourquoi..addEventListener()
cependant, génèrerait une erreur (au moins dans Firefox): TypeError: l'argument 2 de EventTarget.addEventListener n'est pas un objet .Gestionnaires d'événements en ligne (
onevent
attribut HTML)Exemple de code:
Afficher l'extrait de code
De même
element.onevent
, c'est maintenant découragé. Outre les problèmes quielement.onevent
ont, il:Content-Security-Policy
en-tête HTTP approprié pour bloquer les scripts en ligne et autoriser les scripts externes uniquement à partir de domaines approuvés. Voir Comment fonctionne la politique de sécurité du contenu?Voir également
EventTarget.addEventListener()
documentation (MDN)EventTarget.removeEventListener()
documentation (MDN)la source
Bien que
onclick
fonctionne dans tous les navigateurs,addEventListener
ne fonctionne pas dans les anciennes versions d'Internet Explorer, qui utilise à laattachEvent
place.L'inconvénient
onclick
est qu'il ne peut y avoir qu'un seul gestionnaire d'événements, tandis que les deux autres déclenchent tous les rappels enregistrés.la source
Pour autant que je sache, l'événement DOM "load" ne fonctionne toujours que de manière très limitée. Cela signifie que cela ne fera que le feu pour la
window object
,images
et des<script>
éléments par exemple. Il en va de même pour l'onload
affectation directe . Il n'y a pas de différence technique entre ces deux-là. Possède probablement.onload =
une meilleure disponibilité multi-navigateurs.Cependant, vous ne pouvez pas attribuer un
load event
à un<div>
ou<span>
élément ou autres joyeusetés.la source
Sommaire:
addEventListener
peut ajouter plusieurs événements, alors queonclick
cela ne peut pas être fait.onclick
peut être ajouté en tantHTML
qu'attribut, alors que anaddEventListener
ne peut être ajouté qu'au sein des<script>
éléments.addEventListener
peut prendre un troisième argument qui peut arrêter la propagation de l'événement.Les deux peuvent être utilisés pour gérer des événements. Cependant,
addEventListener
devrait être le choix préféré car il peut tout faireonclick
et plus encore. N'utilisez pasonclick
les attributs HTML en ligne car cela confond le javascript et le HTML, ce qui est une mauvaise pratique. Cela rend le code moins maintenable.la source
onclick
handlrs en ligne de peur de rire de la pièce - mais généralement les événements sont liés de façon bien pire et moins d'entretien ces dernières années. Les classes aimentjs-link
,js-form-validation
ou les données attributs avecdata-jspackage="init"
est en aucun cas mieux ... Et comment ofteen vous réellement utiliser bullage d'événement? Personnellement, j'aimerais pouvoir écrire un gestionnaire sans vérifier si la cible correspond réellement à mon élément - ou avoir à arrêter la propagation à plusieurs endroits en raison de bogues aléatoires.Un détail n'a pas encore été noté: les navigateurs de bureau modernes considèrent les différentes pressions de boutons comme des "clics" pour
AddEventListener('click'
etonclick
par défaut.onclick
etAddEventListener
cliquez sur le clic gauche et central.onclick
déclenche uniquement sur le clic gauche, maisAddEventListener
sur les clics gauche, central et droit.En outre, le comportement du clic central est très incohérent entre les navigateurs lorsque les curseurs de défilement sont impliqués:
Il convient également de noter que les événements de «clic» pour tout élément HTML sélectionnable au clavier tels que
input
se déclenchent également sur l'espace ou entrent lorsque l'élément est sélectionné.la source
Javascript a tendance à tout mélanger en objets et cela peut être source de confusion. Tout en un est la manière JavaScript.
Onclick est essentiellement un attribut HTML. Inversement, addEventListener est une méthode sur l'objet DOM représentant un élément HTML.
Dans les objets JavaScript, une méthode est simplement une propriété qui a une fonction en tant que valeur et qui fonctionne avec l'objet auquel elle est attachée (en l'utilisant par exemple).
En JavaScript, l'élément HTML représenté par DOM aura ses attributs mappés sur ses propriétés.
C'est là que les gens sont confus parce que JavaScript fusionne tout en un seul conteneur ou espace de noms sans couche d'indirection.
Dans une disposition OO normale (qui fusionne au moins l'espace de noms des propriétés / méthodes), vous pourriez avoir quelque chose comme:
Il existe des variantes telles qu'il pourrait utiliser un getter / setter pour onload ou HashMap pour les attributs, mais en fin de compte, c'est à quoi cela ressemblerait. JavaScript a éliminé cette couche d'indirection dans l'espoir de savoir ce qui est entre autres choses. Il a fusionné domElement et les attributs ensemble.
Sauf compatibilité, vous devez utiliser comme meilleure pratique addEventListener. Comme d'autres réponses parlent des différences à cet égard plutôt que des différences programmatiques fondamentales, je vais y renoncer. Essentiellement, dans un monde idéal, vous ne devez vraiment utiliser que * à partir de HTML, mais dans un monde encore plus idéal, vous ne devriez rien faire de tel à partir de HTML.
Pourquoi est-il dominant aujourd'hui? Il est plus rapide à écrire, plus facile à apprendre et a tendance à fonctionner.
Le point de charge entier en HTML est de donner accès à la méthode ou à la fonctionnalité addEventListener en premier lieu. En l'utilisant dans JS, vous passez par HTML alors que vous pourriez l'appliquer directement.
En théorie, vous pouvez créer vos propres attributs:
Ce que JS fait avec est un peu différent de cela.
Vous pouvez l'assimiler à quelque chose comme (pour chaque élément créé):
Les détails de mise en œuvre réels différeront probablement avec une gamme de variations subtiles rendant les deux légèrement différents dans certains cas, mais c'est l'essentiel.
C'est sans doute un hack de compatibilité que vous pouvez épingler une fonction à un attribut on car par défaut les attributs sont toutes des chaînes.
la source
Selon MDN , la différence est la suivante:
addEventListener:
sur clic:
Il existe également une différence de syntaxe d'utilisation, comme vous pouvez le voir dans les codes ci-dessous:
addEventListener:
sur clic:
la source
Si vous n'êtes pas trop inquiet à propos de la prise en charge du navigateur, il existe un moyen de relier la référence «this» dans la fonction appelée par l'événement. Il pointera normalement sur l'élément qui a généré l'événement lorsque la fonction est exécutée, ce qui n'est pas toujours ce que vous voulez. La partie délicate est de pouvoir en même temps supprimer le même écouteur d'événements, comme indiqué dans cet exemple: http://jsfiddle.net/roenbaeck/vBYu3/
Le code ci-dessus fonctionne bien dans Chrome, et il y a probablement une petite astuce pour rendre "bind" compatible avec d'autres navigateurs.
la source
L'utilisation de gestionnaires en ligne est incompatible avec la stratégie de sécurité du contenu, de sorte que l'
addEventListener
approche est plus sécurisée de ce point de vue. Bien sûr, vous pouvez activer les gestionnaires en ligne avecunsafe-inline
mais, comme son nom l'indique, ce n'est pas sûr car cela ramène toutes les hordes d'exploits JavaScript que CSP empêche.la source
Il devrait également être possible soit d'étendre l'auditeur en le prototypant (si nous avons une référence à lui et ce n'est pas une fonction anonyme) -ou de faire l'appel 'onclick' à un appel à une bibliothèque de fonctions (une fonction appelant d'autres fonctions)
comme
cela signifie que nous n'avons jamais à poursuivre l'appel onclick, il suffit de modifier la fonction myFunctionList () pour faire ce que nous voulons, mais cela nous laisse sans contrôle des phases de propagation / capture, donc devrait être évité pour les nouveaux navigateurs.
juste au cas où quelqu'un trouverait ce fil à l'avenir ...
la source
Ils font apparemment la même chose: écouter l'événement click et exécuter une fonction de rappel. Néanmoins, ils ne sont pas équivalents. Si jamais vous avez besoin de choisir entre les deux, cela pourrait vous aider à déterminer lequel vous convient le mieux.
La principale différence est que l' onclick n'est qu'une propriété et, comme toutes les propriétés d'objet, si vous écrivez plusieurs fois, elle sera écrasée . Avec addEventListener () à la place, nous pouvons simplement lier un gestionnaire d'événements à l'élément, et nous pouvons l'appeler chaque fois que nous en avons besoin sans nous soucier des propriétés écrasées. Un exemple est montré ici,
Essayez-le: https://jsfiddle.net/fjets5z4/5/
En premier lieu, j'ai été tenté de continuer à utiliser onclick, car il est plus court et semble plus simple… et en fait, il l'est. Mais je ne recommande plus de l'utiliser. C'est comme utiliser JavaScript en ligne. L'utilisation de quelque chose comme - c'est du JavaScript en ligne - est fortement déconseillée de nos jours (le CSS en ligne est également déconseillé, mais c'est un autre sujet).
Cependant, la fonction addEventListener (), bien que ce soit la norme, ne fonctionne tout simplement pas dans les anciens navigateurs (Internet Explorer sous la version 9), et c'est une autre grande différence. Si vous devez prendre en charge ces anciens navigateurs, vous devez suivre la méthode onclick. Mais vous pouvez également utiliser jQuery (ou l'une de ses alternatives): il simplifie fondamentalement votre travail et réduit les différences entre les navigateurs, ce qui peut vous faire gagner beaucoup de temps.
la source
addEventListener
vous permet de définir plusieurs gestionnaires, mais n'est pas pris en charge dans IE8 ou inférieur.IE a
attachEvent
, mais ce n'est pas exactement la même chose.la source
Le contexte référencé par
'this'
mot-clé dans JavasSript est différent.regardez le code suivant:
Ce qu'il fait est vraiment simple. lorsque vous cliquez sur le bouton, le bouton est automatiquement désactivé.
Tout d'abord, lorsque vous essayez de connecter les événements de cette manière, l'
button.onclick = function(),
événement onclick sera déclenché en cliquant sur le bouton, cependant, le bouton ne sera pas désactivé car il n'y a pas de liaison explicite entre button.onclick et le gestionnaire d'événements onclick. Si vous déboguez voir l''this'
objet, vous pouvez voir qu'il fait référence à l''window'
objet.Deuxièmement, si vous commentez
btnSubmit.onclick = disable();
et décommentez,//btnSubmit.addEventListener('click', disable, false);
vous pouvez voir que le bouton est désactivé car de cette façon, il existe une liaison explicite entre l'événement button.onclick et le gestionnaire d'événements onclick. Si vous déboguez dans la fonction de désactivation, vous pouvez voir se'this'
réfère aubutton control
plutôt qu'auwindow
.C'est quelque chose que je n'aime pas dans JavaScript qui est une incohérence. Btw, si vous utilisez jQuery (
$('#btnSubmit').on('click', disable);
), il utilise une liaison explicite.la source
btnSubmit.onclick = disable;
(attribuer une fonction, pas l'appeler). Ensuite, dans les deux cas,this
fera référence à l'élément bouton.onclick est essentiellement un addEventListener qui exécute spécifiquement une fonction lorsque l'élément est cliqué. Donc, utile lorsque vous avez un bouton qui effectue des opérations simples, comme un bouton de calculatrice. addEventlistener peut être utilisé pour une multitude de choses comme effectuer une opération lorsque DOM ou tout le contenu est chargé, semblable à window.onload mais avec plus de contrôle.
Remarque, vous pouvez réellement utiliser plus d'un événement avec inline, ou au moins en utilisant onclick en séparant chaque fonction avec un point-virgule, comme ceci ....
Je n'écrirais pas une fonction avec inline, car vous pourriez potentiellement avoir des problèmes plus tard et ce serait désordonné imo. Utilisez-le simplement pour appeler des fonctions déjà effectuées dans votre fichier de script.
Lequel vous utilisez, je suppose, dépendra de ce que vous voulez. addEventListener pour les opérations complexes et onclick pour simple. J'ai vu que certains projets n'attachaient pas un élément spécifique aux éléments et implémenteraient plutôt un écouteur d'événements plus global qui déterminerait si un tap était sur un bouton et effectuer certaines tâches en fonction de ce qui était pressé. Je pense que cela pourrait potentiellement conduire à des problèmes, et même s'il est petit, probablement, un gaspillage de ressources si cet écouteur d'événements devait gérer chaque clic
la source