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)); }