Entrambi sono corretti, ma nessuno di essi è "il migliore" di per sé e potrebbe esserci un motivo per cui lo sviluppatore ha scelto di utilizzare entrambi gli approcci.
Listener di eventi (addEventListener e IE's attachEvent)
Le versioni precedenti di Internet Explorer implementano javascript in modo diverso da qualsiasi altro browser. Con versioni inferiori a 9, si utilizza il metodo attachEvent
[ doc ], in questo modo:
element.attachEvent('onclick', function() { /* do stuff here*/ });
Nella maggior parte degli altri browser (incluso IE 9 e versioni successive), usi addEventListener
[ doc ], in questo modo:
element.addEventListener('click', function() { /* do stuff here*/ }, false);
Utilizzando questo approccio ( eventi DOM livello 2 ), è possibile collegare un numero teoricamente illimitato di eventi a qualsiasi singolo elemento. L'unica limitazione pratica è la memoria lato client e altri problemi di prestazioni, che sono diversi per ciascun browser.
Gli esempi precedenti rappresentano l'utilizzo di una funzione anonima [ doc ]. Puoi anche aggiungere un listener di eventi usando un riferimento di funzione [ doc ] o una chiusura [ doc ]:
var myFunctionReference = function() { /* do stuff here*/ }
element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);
Un'altra caratteristica importante di addEventListener
è il parametro finale, che controlla il modo in cui l'ascoltatore reagisce agli eventi gorgoglianti [ doc ]. Ho passato falsi negli esempi, che è standard per probabilmente il 95% dei casi d'uso. Non esiste un argomento equivalente per attachEvent
o quando si utilizzano eventi inline.
Eventi incorporati (HTML onclick = "" proprietà ed element.onclick)
In tutti i browser che supportano JavaScript, puoi mettere in linea un listener di eventi, il che significa proprio nel codice HTML. Probabilmente hai visto questo:
<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>
Gli sviluppatori più esperti evitano questo metodo, ma ottiene il lavoro fatto; è semplice e diretto. Non è possibile utilizzare chiusure o funzioni anonime qui (anche se il gestore stesso è una sorta di funzione anonima) e il controllo dell'ambito è limitato.
L'altro metodo che menzioni:
element.onclick = function () { /*do stuff here */ };
... è l'equivalente di JavaScript inline, tranne per il fatto che hai un maggiore controllo dell'ambito (poiché stai scrivendo uno script anziché HTML) e puoi utilizzare funzioni anonime, riferimenti di funzione e / o chiusure.
Lo svantaggio significativo degli eventi inline è che, diversamente dai listener di eventi sopra descritti, è possibile assegnare un solo evento inline. Gli eventi incorporati sono memorizzati come un attributo / proprietà dell'elemento [ doc ], il che significa che può essere sovrascritto.
Utilizzando l'esempio <a>
dall'HTML sopra:
var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };
... quando fai clic sull'elemento, vedrai solo "Did stuff # 2" - hai sovrascritto il primo assegnato della onclick
proprietà con il secondo valore e hai sovrascritto anche la onclick
proprietà HTML incorporata originale . Dai un'occhiata qui: http://jsfiddle.net/jpgah/ .
In linea di massima, non utilizzare eventi in linea . Potrebbero esserci casi d'uso specifici per questo, ma se non sei sicuro al 100% di avere quel caso d'uso, allora non devi e non dovresti usare eventi in linea.
Javascript moderno (angolare e simili)
Da quando questa risposta è stata originariamente pubblicata, i framework javascript come Angular sono diventati molto più popolari. Vedrai un codice come questo in un modello angolare:
<button (click)="doSomething()">Do Something</button>
Sembra un evento in linea, ma non lo è. Questo tipo di modello verrà trasformato in codice più complesso che utilizza i listener di eventi dietro le quinte. Tutto ciò che ho scritto sugli eventi qui si applica ancora, ma tu sei rimosso dal grintoso nocciolo di almeno uno strato. Dovresti capire i dettagli, ma se le tue migliori pratiche del framework JS moderno prevedono la scrittura di questo tipo di codice in un modello, non pensare di utilizzare un evento in linea - non lo sei.
Qual è il migliore?
La domanda è una questione di compatibilità e necessità del browser. Devi collegare più di un evento a un elemento? Lo farai in futuro? Le probabilità sono, lo farai. attachEvent e addEventListener sono necessari. Altrimenti, un evento in linea può sembrare che farebbero il trucco, ma sei molto meglio servito a prepararti per un futuro che, sebbene possa sembrare improbabile, almeno è prevedibile. È possibile che tu debba passare a listener di eventi basati su JS, quindi potresti anche iniziare da lì. Non utilizzare eventi in linea.
jQuery e altri framework javascript incapsulano le diverse implementazioni del browser degli eventi di livello DOM 2 in modelli generici in modo da poter scrivere codice conforme a più browser senza doversi preoccupare della storia di IE come ribelle. Stesso codice con jQuery, tutto cross-browser e pronto per il rock:
$(element).on('click', function () { /* do stuff */ });
Non finire e ottenere un framework solo per questa cosa, però. Puoi facilmente girare la tua piccola utility per occuparti dei browser più vecchi:
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!'); }
);
Provalo: http://jsfiddle.net/bmArj/
Considerando tutto ciò, a meno che lo script che stai osservando non tenga conto delle differenze del browser in un altro modo (nel codice non mostrato nella tua domanda), la parte che utilizza addEventListener
non funzionerebbe nelle versioni di IE inferiori a 9.
Documentazione e lettura correlata
function addEvent(element, myEvent, fnc) { return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false)); }