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)); }
function addEvent(e,n,f){return e.attachEvent?e.attachEvent('on'+n,f):e.addEventListener(n,f,!!0)}
<< Pada 98 karakter, yang ini lebih dari 40% lebih kecil!Perbedaan yang bisa Anda lihat jika Anda memiliki beberapa fungsi lain:
Fungsi 2, 3 dan 4 berfungsi, tetapi 1 tidak. Hal ini karena
addEventListener
tidak menimpa penangan acara yang ada, sedangkanonclick
menimpaonclick = fn
penangan acara yang ada .Perbedaan signifikan lainnya, tentu saja, adalah yang
onclick
akan selalu berfungsi, sedangkanaddEventListener
tidak bekerja di Internet Explorer sebelum versi 9. Anda dapat menggunakan analogattachEvent
(yang memiliki sintaks yang sedikit berbeda) di IE <9.sumber
Dalam jawaban ini saya akan menjelaskan tiga metode pendefinisian event DOM.
element.addEventListener()
Contoh kode:
Tampilkan cuplikan kode
element.addEventListener()
memiliki beberapa keunggulan:element.removeEventListener()
.useCapture
parameter, yang menunjukkan apakah Anda ingin menangani acara dalam fase menangkap atau menggelegak . Lihat: Tidak dapat memahami atribut useCapture di addEventListener ..onevent
properti elemen DOM, banyak pemrogram JavaScript yang tidak berpengalaman berpikir bahwa nama acara adalah sebagai contohonclick
atauonload
.on
adalah tidak bagian dari nama acara . Nama acara yang benar adalahclick
danload
, dan itulah bagaimana nama acara diteruskan ke.addEventListener()
.element.onevent = function() {}
(misalnyaonclick
,onload
)Contoh kode:
Tampilkan cuplikan kode
Ini adalah cara untuk mendaftarkan penangan acara di DOM 0. Sekarang tidak disarankan, karena:
onevent
properti kembali ke keadaan awal (yaitunull
).window.onload
, misalnya:,window.onload = "test";
itu tidak akan menghasilkan kesalahan. Kode Anda tidak akan berfungsi dan akan sangat sulit untuk menemukan alasannya..addEventListener()
namun, akan menimbulkan kesalahan (setidaknya di Firefox): TypeError: Argumen 2 dari EventTarget.addEventListener bukan objek .Penangan acara sebaris (
onevent
atribut HTML)Contoh kode:
Tampilkan cuplikan kode
Demikian pula untuk
element.onevent
, sekarang tidak disarankan. Selain masalah yangelement.onevent
ada, itu:Content-Security-Policy
tajuk HTTP yang tepat untuk memblokir skrip inline dan mengizinkan skrip eksternal hanya dari domain tepercaya. Lihat Bagaimana cara kerja Kebijakan Keamanan Konten?Lihat juga
EventTarget.addEventListener()
dokumentasi (MDN)EventTarget.removeEventListener()
dokumentasi (MDN)sumber
Saat
onclick
berfungsi di semua browser,addEventListener
tidak bekerja di versi Internet Explorer yang lebih lama, yang digunakanattachEvent
sebagai gantinya.Kelemahannya
onclick
adalah bahwa hanya ada satu event handler, sedangkan dua lainnya akan memecat semua callback terdaftar.sumber
Sejauh yang saya tahu, acara "memuat" DOM masih bekerja dengan sangat terbatas. Itu berarti hanya akan menyala untuk
window object
,images
dan<script>
elemen misalnya. Hal yang sama berlaku untukonload
penugasan langsung . Tidak ada perbedaan teknis antara keduanya. Mungkin.onload =
memiliki ketersediaan lintas-browser yang lebih baik.Namun, Anda tidak dapat menetapkan
load event
ke<div>
atau<span>
elemen atau entah apa lagi.sumber
Ringkasan:
addEventListener
dapat menambahkan beberapa acara, sedangkan denganonclick
ini tidak dapat dilakukan.onclick
dapat ditambahkan sebagaiHTML
atribut, sedangkan anaddEventListener
hanya dapat ditambahkan dalam<script>
elemen.addEventListener
dapat mengambil argumen ketiga yang dapat menghentikan propagasi acara.Keduanya bisa digunakan untuk menangani acara. Namun,
addEventListener
harus menjadi pilihan yang disukai karena dapat melakukan segalanyaonclick
dan lebih banyak lagi. Jangan gunakan inlineonclick
sebagai atribut HTML karena ini mencampur javascript dan HTML yang merupakan praktik buruk. Itu membuat kode kurang bisa dipelihara.sumber
onclick
handlrs karena takut ditertawakan keluar ruangan - tetapi biasanya peristiwa terikat jauh lebih buruk dan kurang terawat dalam beberapa tahun terakhir. Kelas sukajs-link
,js-form-validation
atau atribut datadata-jspackage="init"
sama sekali tidak lebih baik ... Dan seberapa sering Anda benar-benar menggunakan event bubbling? Saya pribadi ingin sekali dapat menulis handler tanpa memeriksa apakah targetnya benar-benar cocok dengan elemen saya - atau harus menghentikan propagasi di beberapa tempat karena bug acak.Satu detail belum dicatat: browser desktop modern menganggap penekanan tombol yang berbeda sebagai "klik" untuk
AddEventListener('click'
danonclick
secara default.onclick
danAddEventListener
klik api di klik kiri dan tengah.onclick
jalankan hanya pada klik kiri, tetapiAddEventListener
klik api pada klik kiri, tengah dan kanan.Selain itu, perilaku klik tengah sangat tidak konsisten di seluruh browser saat kursor gulir terlibat:
Perlu juga dicatat bahwa acara "klik" untuk elemen HTML yang dapat dipilih dengan keyboard seperti
input
juga mengaktifkan ruang atau masuk saat elemen dipilih.sumber
Javascript cenderung untuk memadukan semuanya menjadi objek dan itu dapat membuatnya membingungkan. Semua menjadi satu adalah cara JavaScript.
Pada dasarnya onclick adalah atribut HTML. Sebaliknya addEventListener adalah metode pada objek DOM yang mewakili elemen HTML.
Dalam objek JavaScript, metode hanyalah properti yang memiliki fungsi sebagai nilai dan yang berfungsi terhadap objek yang dilampirkan (menggunakan ini misalnya).
Dalam JavaScript sebagai elemen HTML yang diwakili oleh DOM akan memiliki atribut itu dipetakan ke propertinya.
Di sinilah orang menjadi bingung karena JavaScript menggabungkan semuanya ke dalam satu wadah atau namespace tanpa lapisan tipuan.
Dalam tata letak OO normal (yang setidaknya menggabungkan namespace dari properti / metode) Anda mungkin memiliki sesuatu seperti:
Ada variasi seperti itu bisa menggunakan pengambil / penyetel untuk onload atau HashMap untuk atribut tetapi pada akhirnya itulah yang akan terlihat. JavaScript menghilangkan lapisan tipuan dengan harapan mengetahui apa yang ada di antara hal-hal lain. Itu menggabungkan domElement dan atribut bersama.
Cegah kompatibilitas Anda harus sebagai praktik terbaik menggunakan addEventListener. Ketika jawaban lain berbicara tentang perbedaan dalam hal itu daripada perbedaan program yang mendasar, saya akan melupakannya. Pada dasarnya, di dunia ideal Anda benar-benar hanya dimaksudkan untuk menggunakan * dari HTML tetapi di dunia yang lebih ideal Anda tidak harus melakukan hal seperti itu dari HTML.
Mengapa hari ini dominan? Lebih cepat menulis, lebih mudah dipelajari dan cenderung hanya bekerja.
Seluruh titik onload dalam HTML adalah untuk memberikan akses ke metode addEventListener atau fungsi di tempat pertama. Dengan menggunakannya di JS Anda akan melalui HTML ketika Anda bisa menerapkannya secara langsung.
Secara hipotesis Anda dapat membuat atribut Anda sendiri:
Apa yang dilakukan JS sedikit berbeda dengan itu.
Anda dapat menyamakannya dengan sesuatu seperti (untuk setiap elemen yang dibuat):
Detail implementasi yang sebenarnya kemungkinan akan berbeda dengan serangkaian variasi yang halus membuat keduanya sedikit berbeda dalam beberapa kasus, tetapi itulah intinya.
Ini bisa dibilang hack kompatibilitas yang dapat Anda pin fungsi ke atribut on karena atribut default adalah semua string.
sumber
Menurut MDN , perbedaannya adalah sebagai berikut:
addEventListener:
onclick:
Ada juga perbedaan sintaks yang digunakan seperti yang Anda lihat dalam kode di bawah ini:
addEventListener:
onclick:
sumber
Jika Anda tidak terlalu khawatir tentang dukungan browser, ada cara untuk memutar ulang referensi 'ini' dalam fungsi yang dipanggil oleh acara tersebut. Biasanya akan menunjuk ke elemen yang menghasilkan acara ketika fungsi dieksekusi, yang tidak selalu seperti yang Anda inginkan. Bagian yang sulit adalah pada saat yang sama dapat menghapus pendengar acara yang sama, seperti yang ditunjukkan dalam contoh ini: http://jsfiddle.net/roenbaeck/vBYu3/
Kode di atas berfungsi baik di Chrome, dan mungkin ada beberapa shim sekitar yang membuat "bind" kompatibel dengan browser lain.
sumber
Menggunakan penangan sebaris tidak kompatibel dengan Kebijakan Keamanan Konten sehingga
addEventListener
pendekatan lebih aman dari sudut pandang itu. Tentu saja Anda dapat mengaktifkan penangan inline denganunsafe-inline
tetapi, seperti namanya, itu tidak aman karena membawa kembali seluruh gerombolan eksploitasi JavaScript yang mencegah CSP.sumber
Harus juga dimungkinkan untuk memperpanjang pendengar dengan membuat prototipe (jika kita memiliki referensi untuk itu dan itu bukan fungsi anonim) -atau membuat panggilan onclick panggilan ke perpustakaan fungsi (fungsi memanggil fungsi lain)
Suka
ini berarti kita tidak pernah harus membalas panggilan onclick hanya mengubah fungsi myFunctionList () untuk melakukan apa pun yang kita inginkan, tetapi ini membuat kita tanpa kontrol fase menggelembung / menangkap sehingga harus dihindari untuk browser yang lebih baru.
kalau-kalau seseorang menemukan utas ini di masa depan ...
sumber
Mereka tampaknya melakukan hal yang sama: mendengarkan acara klik dan menjalankan fungsi panggilan balik. Namun demikian, mereka tidak setara. Jika Anda perlu memilih di antara keduanya, ini bisa membantu Anda untuk mencari tahu mana yang terbaik untuk Anda.
Perbedaan utama adalah bahwa onclick hanyalah sebuah properti , dan seperti semua properti objek, jika Anda menulis lebih dari satu kali, itu akan ditimpa . Sebagai gantinya dengan addEventListener () , kita bisa mengikat event handler ke elemen, dan kita bisa memanggilnya setiap kali kita membutuhkannya tanpa khawatir akan properti yang ditimpa. Contoh ditunjukkan di sini,
Cobalah: https://jsfiddle.net/fjets5z4/5/
Pertama-tama saya tergoda untuk terus menggunakan onclick, karena lebih pendek dan terlihat lebih sederhana ... dan kenyataannya memang demikian. Tapi saya tidak merekomendasikan menggunakannya lagi. Ini seperti menggunakan JavaScript sebaris. Menggunakan sesuatu seperti - itu inline JavaScript - sangat tidak disukai saat ini (CSS inline juga tidak disarankan, tapi itu topik lain).
Namun, fungsi addEventListener (), meskipun standar, tidak berfungsi di browser lama (Internet Explorer di bawah versi 9), dan ini adalah perbedaan besar lainnya. Jika Anda perlu mendukung browser kuno ini, Anda harus mengikuti cara onclick. Tetapi Anda juga bisa menggunakan jQuery (atau salah satu alternatifnya): pada dasarnya menyederhanakan pekerjaan Anda dan mengurangi perbedaan antar browser, karena itu dapat menghemat banyak waktu.
sumber
addEventListener
memungkinkan Anda mengatur beberapa penangan, tetapi tidak didukung di IE8 atau lebih rendah.IE memang punya
attachEvent
, tapi tidak persis sama.sumber
Konteks yang dirujuk oleh
'this'
kata kunci di JavasSript berbeda.lihat kode berikut:
Apa yang dilakukannya sangat sederhana. ketika Anda mengklik tombol, tombol akan dinonaktifkan secara otomatis.
Pertama ketika Anda mencoba untuk menghubungkan peristiwa dengan cara ini,
button.onclick = function(),
acara onclick akan dipicu dengan mengklik tombol, namun tombol tidak akan dinonaktifkan karena tidak ada ikatan yang eksplisit antara button.onclick dan onclick event handler. Jika Anda debug melihat'this'
objek, Anda bisa melihatnya mengacu pada'window'
objek.Kedua, jika Anda berkomentar
btnSubmit.onclick = disable();
dan menghapus komentar,//btnSubmit.addEventListener('click', disable, false);
Anda dapat melihat bahwa tombol dinonaktifkan karena dengan cara ini ada ikatan eksplisit antara button.onclick event dan onclick event handler. Jika Anda men-debug ke fungsi menonaktifkan, Anda dapat melihat'this'
merujuk kebutton control
bukanwindow
.Ini adalah sesuatu yang saya tidak suka tentang JavaScript yang tidak konsisten. Btw, jika Anda menggunakan jQuery (
$('#btnSubmit').on('click', disable);
), ia menggunakan pengikatan eksplisit.sumber
btnSubmit.onclick = disable;
(menetapkan fungsi, bukan menyebutnya). Kemudian dalam kedua kasusthis
akan merujuk ke elemen tombol.onclick pada dasarnya adalah addEventListener yang secara khusus melakukan fungsi ketika elemen diklik. Jadi, berguna ketika Anda memiliki tombol yang melakukan operasi sederhana, seperti tombol kalkulator. addEventlistener dapat digunakan untuk banyak hal seperti melakukan operasi ketika DOM atau semua konten dimuat, mirip dengan window.onload tetapi dengan kontrol lebih.
Catatan, Anda benar-benar dapat menggunakan lebih dari satu peristiwa dengan inline, atau setidaknya dengan menggunakan onclick dengan memisahkan setiap fungsi dengan titik koma, seperti ini ....
Saya tidak akan menulis fungsi dengan inline, karena Anda berpotensi memiliki masalah di kemudian hari dan itu akan berantakan. Cukup gunakan untuk memanggil fungsi yang sudah dilakukan dalam file skrip Anda.
Yang mana yang Anda gunakan saya kira akan tergantung pada apa yang Anda inginkan. addEventListener untuk operasi kompleks dan klik sederhana. Saya telah melihat beberapa proyek tidak melampirkan proyek tertentu ke elemen dan sebaliknya akan mengimplementasikan daftar acara yang lebih global yang akan menentukan apakah ketukan pada tombol dan melakukan tugas tertentu tergantung pada apa yang ditekan. Imo yang berpotensi menyebabkan masalah, saya pikir, dan meskipun kecil, mungkin, pemborosan sumber daya jika pemilik acara harus menangani setiap klik
sumber