Les deux sont correctes, mais aucune n'est "meilleure" 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 mettent en œuvre le javascript différemment de presque tous les autres navigateurs. Avec les versions inférieures à 9, vous utilisez la fonction 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 du niveau 2 de DOM ), vous pouvez attacher un nombre théoriquement illimité d'événements à un seul élément. La seule limite pratique est la mémoire côté client et d'autres problèmes de performance, 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 en utilisant une référence de fonction [ doc ] ou 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 dernier paramètre, qui contrôle la façon dont l'écouteur réagit aux événements de bulles[ doc ]. J'ai passé false 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 supportent le javascript, vous pouvez placer un écouteur d'événements en ligne, c'est-à-dire directement dans le code HTML. Vous avez probablement vu ceci :
<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>
La plupart des développeurs expérimentés fuient cette méthode, mais elle permet de faire le travail ; elle est simple et directe. Vous ne pouvez pas utiliser de fermetures ou de fonctions anonymes ici (bien que le gestionnaire lui-même soit une fonction anonyme en quelque sorte), 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 du HTML) et que vous pouvez utiliser des fonctions anonymes, des références de fonctions 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, un seul événement en ligne peut être attribué. 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 écrasé.
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'); };
... quand vous cliquez sur l'élément, vous avez sólo voir "Fait des trucs #2" - vous avez écrasé la première assignation de la onclick
avec la deuxième valeur, et vous avez écrasé la propriété HTML en ligne d'origine. onclick
la propriété aussi. Regardez ici : http://jsfiddle.net/jpgah/ .
De manière générale, ne pas utiliser les é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% d'avoir ce cas d'utilisation, alors vous ne devez pas utiliser les événements en ligne.
Javascript moderne (Angular et autres)
Depuis que cette réponse a été publiée, les frameworks javascript comme Angular sont devenus beaucoup plus populaires. Vous verrez du code comme celui-ci dans un modèle Angular :
<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é dans du code plus complexe qui utilise des écouteurs d'événements dans les coulisses. Tout ce que j'ai écrit ici sur les événements reste valable, mais vous êtes éloigné des détails d'au moins une couche. Vous devez comprendre les rouages, mais si les meilleures pratiques de votre framework JS moderne impliquent d'écrire ce type de code dans un template, n'ayez pas l'impression d'utiliser un événement inline - ce n'est pas le cas.
Quelle est la meilleure solution ?
La question est une question de compatibilité des navigateurs et de nécessité. Avez-vous besoin d'attacher plus d'un événement à un élément ? Le ferez-vous à l'avenir ? Il y a de fortes chances que oui. attachEvent et addEventListener sont nécessaires. Si ce n'est pas le cas, un événement en ligne peut sembler faire l'affaire, mais il vaut mieux se préparer à un avenir qui, même s'il semble improbable, est au moins prévisible. Il est possible que vous deviez passer à des écouteurs d'événements basés sur JS, alors autant commencer par là. N'utilisez pas d'événements en ligne.
jQuery et d'autres frameworks javascript encapsulent les implémentations des différents navigateurs des événements de niveau 2 du DOM dans des modèles génériques afin que vous puissiez écrire un code compatible avec tous les navigateurs sans avoir à vous soucier de l'histoire d'IE comme rebelle. Le même code avec jQuery, compatible avec tous les navigateurs et prêt à fonctionner :
$(element).on('click', function () { /* do stuff */ });
Mais ne vous précipitez pas pour acheter un framework juste pour cette raison. Vous pouvez facilement créer votre propre petit utilitaire pour prendre en charge les 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 prenant tout cela en considération, à moins que le script que vous regardez n'ait pris en compte les différences entre les navigateurs d'une autre manière (dans un code qui n'est pas montré dans votre question), la partie qui utilise addEventListener
ne fonctionnerait pas dans les versions d'IE inférieures à 9.
Documentation et lectures connexes