Keduanya benar, tetapi tidak ada yang "terbaik" per se, dan mungkin ada alasan pengembang memilih untuk menggunakan kedua pendekatan tersebut.
Event Listeners (addEventListener dan IE's attachEvent)
Versi sebelumnya dari Internet Explorer menerapkan javascript berbeda dari hampir semua browser lainnya. Dengan versi yang kurang dari 9, Anda menggunakan metode attachEvent
[ doc ], seperti ini:
element.attachEvent('onclick', function() { /* do stuff here*/ });
Di sebagian besar browser lain (termasuk IE 9 dan lebih tinggi), Anda menggunakan addEventListener
[ doc ], seperti ini:
element.addEventListener('click', function() { /* do stuff here*/ }, false);
Dengan menggunakan pendekatan ini ( peristiwa DOM Level 2 ), Anda dapat melampirkan sejumlah acara yang secara teoritis tidak terbatas ke elemen tunggal apa pun. Satu-satunya batasan praktis adalah memori sisi klien dan masalah kinerja lainnya, yang berbeda untuk setiap browser.
Contoh-contoh di atas mewakili menggunakan fungsi anonim [ doc ]. Anda juga dapat menambahkan pendengar acara menggunakan referensi fungsi [ doc ] atau penutupan [ doc ]:
var myFunctionReference = function() { /* do stuff here*/ }
element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);
Fitur penting lainnya addEventListener
adalah parameter terakhir, yang mengontrol bagaimana pendengar bereaksi terhadap peristiwa [ doc ]. Saya telah memberikan contoh yang salah, yang merupakan standar untuk 95% kasus penggunaan. Tidak ada argumen yang setara untuk attachEvent
, atau saat menggunakan acara inline.
Acara sebaris (HTML onclick = "" properti dan element.onclick)
Di semua browser yang mendukung javascript, Anda dapat menempatkan inener pendengar acara, yang berarti tepat di kode HTML. Anda mungkin pernah melihat ini:
<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>
Kebanyakan pengembang yang berpengalaman menghindari metode ini, tetapi itu menyelesaikan pekerjaan; itu sederhana dan langsung. Anda tidak boleh menggunakan fungsi penutupan atau anonim di sini (meskipun pawang itu sendiri adalah semacam fungsi anonim), dan kendali Anda terhadap ruang lingkup terbatas.
Metode lain yang Anda sebutkan:
element.onclick = function () { /*do stuff here */ };
... setara dengan javascript sebaris kecuali bahwa Anda memiliki kendali lebih besar terhadap ruang lingkup (karena Anda menulis skrip daripada HTML) dan dapat menggunakan fungsi anonim, referensi fungsi, dan / atau penutupan.
Kelemahan signifikan dengan acara inline adalah bahwa tidak seperti pendengar acara yang dijelaskan di atas, Anda mungkin hanya memiliki satu acara inline yang ditugaskan. Acara inline disimpan sebagai atribut / properti dari elemen [ doc ], yang berarti bahwa itu dapat ditimpa.
Menggunakan contoh <a>
dari HTML di atas:
var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };
... ketika Anda mengklik elemen, Anda hanya akan melihat "Melakukan hal # 2" - Anda menimpa yang pertama ditugaskan onclick
properti dengan nilai kedua, dan Anda juga menimpa onclick
properti HTML inline asli juga. Lihat di sini: http://jsfiddle.net/jpgah/ .
Secara umum, jangan gunakan acara inline . Mungkin ada kasus penggunaan khusus untuk itu, tetapi jika Anda tidak 100% yakin Anda memiliki kasus penggunaan itu, maka Anda tidak dan tidak boleh menggunakan inline events.
Javascript Modern (Sudut dan sejenisnya)
Karena jawaban ini awalnya diposting, kerangka kerja javascript seperti Angular telah menjadi jauh lebih populer. Anda akan melihat kode seperti ini di templat Angular:
<button (click)="doSomething()">Do Something</button>
Ini terlihat seperti acara inline, tetapi sebenarnya tidak. Jenis template ini akan ditranskrip ke dalam kode yang lebih kompleks yang menggunakan pendengar acara di belakang layar. Semua yang saya tulis tentang acara di sini masih berlaku, tetapi Anda dihapus dari seluk-beluk oleh setidaknya satu lapisan. Anda harus memahami mur dan baut, tetapi jika praktik terbaik kerangka JS modern Anda melibatkan penulisan kode semacam ini dalam templat, jangan merasa seperti Anda menggunakan acara inline - Anda tidak.
Mana yang Terbaik?
Pertanyaannya adalah masalah kompatibilitas dan kebutuhan browser. Apakah Anda perlu melampirkan lebih dari satu peristiwa ke suatu elemen? Akankah kamu di masa depan? Kemungkinannya adalah Anda akan melakukannya. attachEvent dan addEventListener diperlukan. Jika tidak, acara inline mungkin terlihat seperti mereka akan melakukan trik, tetapi Anda lebih siap melayani untuk masa depan yang, meskipun mungkin tampak tidak mungkin, setidaknya dapat diprediksi. Ada kemungkinan Anda harus pindah ke pendengar acara berbasis JS, jadi sebaiknya mulai saja di sana. Jangan gunakan acara sebaris.
jQuery dan kerangka kerja javascript lainnya merangkum berbagai implementasi browser dari peristiwa DOM level 2 dalam model generik sehingga Anda dapat menulis kode yang sesuai lintas-browser tanpa harus khawatir tentang sejarah IE sebagai pemberontak. Kode yang sama dengan jQuery, semua cross-browser dan siap untuk di-rock:
$(element).on('click', function () { /* do stuff */ });
Namun, jangan kehabisan dan mendapatkan kerangka kerja hanya untuk hal yang satu ini. Anda dapat dengan mudah menggulirkan utilitas kecil Anda sendiri untuk merawat browser lama:
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!'); }
);
Cobalah: http://jsfiddle.net/bmArj/
Mempertimbangkan semua itu, kecuali skrip yang Anda lihat memperhitungkan perbedaan browser dengan cara lain (dalam kode tidak ditampilkan dalam pertanyaan Anda), bagian yang digunakan addEventListener
tidak akan berfungsi di versi IE kurang dari 9.
Dokumentasi dan Bacaan Terkait
function addEvent(element, myEvent, fnc) { return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false)); }