addEventListener vs onclick

704

Apa perbedaan antara addEventListenerdan onclick?

var h = document.getElementById("a");
h.onclick = dothing1;
h.addEventListener("click", dothing2);

Kode di atas berada bersama dalam file .js yang terpisah, dan keduanya bekerja dengan sempurna.

William Sham
sumber

Jawaban:

956

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 addEventListeneradalah 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 onclickproperti dengan nilai kedua, dan Anda juga menimpa onclickproperti 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 addEventListenertidak akan berfungsi di versi IE kurang dari 9.

Dokumentasi dan Bacaan Terkait

Chris Baker
sumber
14
maaf bertemu tetapi hanya ingin memberikan versi ringkas dari fungsi Anda (biola: jsfiddle.net/bmArj/153 ) -function addEvent(element, myEvent, fnc) { return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false)); }
Deryck
10
@Gaurav_soni No. Nama fungsi dan semua kode yang dikandungnya sudah terekspos di file javascript, yang ada di plaintext. Siapa pun dapat membuka konsol web dan menjalankan atau memanipulasi javascript apa pun. Jika javascript Anda mengandung sesuatu yang bisa menjadi risiko keamanan jika terbuka ke publik, maka Anda punya masalah besar karena sudah terekspos ke publik.
Chris Baker
4
Selama kita mengkondensasikan algoritme ini, kita sebaiknya melanjutkan: 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!
Trevor
3
@ Trevor Karena penasaran, mengapa !! 0? Kenapa tidak! 1 atau hanya 0?
Chris Baker
2
@AdrianMoisa Jawaban ini ditulis pada saat AngularJS adalah hal baru yang sedang naik daun, dan praktik umum masih "peningkatan progresif" - yaitu, menulis dokumen HTML dengan cara yang akan bekerja dengan atau tanpa javascript. Dalam perspektif itu, mengikat peristiwa dari javascript akan menjadi praktik terbaik. Saat ini, saya tidak berpikir banyak orang terlalu khawatir tentang peningkatan progresif, terutama tidak mempertimbangkan prevalensi hal-hal seperti Angular. Masih ada beberapa pemisahan kekhawatiran tentang peristiwa inline (tidak menggunakan Angular), tapi itu lebih gaya daripada substansi.
Chris Baker
193

Perbedaan yang bisa Anda lihat jika Anda memiliki beberapa fungsi lain:

var h = document.getElementById('a');
h.onclick = doThing_1;
h.onclick = doThing_2;

h.addEventListener('click', doThing_3);
h.addEventListener('click', doThing_4);

Fungsi 2, 3 dan 4 berfungsi, tetapi 1 tidak. Hal ini karenaaddEventListener tidak menimpa penangan acara yang ada, sedangkan onclickmenimpa onclick = fnpenangan acara yang ada .

Perbedaan signifikan lainnya, tentu saja, adalah yang onclickakan selalu berfungsi, sedangkan addEventListenertidak bekerja di Internet Explorer sebelum versi 9. Anda dapat menggunakan analog attachEvent(yang memiliki sintaks yang sedikit berbeda) di IE <9.

lonesomeday
sumber
18
Itu penjelasan yang sangat jelas! Tepat pada intinya. Jadi jika saya memerlukan banyak fungsi untuk satu acara, saya terjebak dengan addEventListener, dan saya harus menulis lebih banyak kode untuk attachEvent hanya untuk mengakomodasi IE.
William Sham
4
2, 3, dan 4 harus dinamai dosomething. 1 akan ditimpa oleh 2 dan tidak pernah dipanggil.
DragonLord
Memang penjelasan yang sangat jelas dan to-the-point. Baik itu memang lebih masuk akal untuk memberi nama fungsi 'doThing_1', dll. (Jika Anda masih ingin memenuhi IE <9, lihat jawaban Chris.)
Frank Conijn
61

Dalam jawaban ini saya akan menjelaskan tiga metode pendefinisian event DOM.

element.addEventListener()

Contoh kode:

element.addEventListener() memiliki beberapa keunggulan:

  • Memungkinkan Anda mendaftarkan penangan acara tanpa batas dan menghapusnya element.removeEventListener().
  • Memiliki useCaptureparameter, yang menunjukkan apakah Anda ingin menangani acara dalam fase menangkap atau menggelegak . Lihat: Tidak dapat memahami atribut useCapture di addEventListener .
  • Peduli tentang semantik . Pada dasarnya, ini membuat pendaftaran penangan acara lebih eksplisit. Untuk seorang pemula, pemanggilan fungsi membuatnya jelas bahwa sesuatu terjadi , sedangkan menempatkan peristiwa ke beberapa properti elemen DOM setidaknya tidak intuitif.
  • Memungkinkan Anda memisahkan struktur dokumen (HTML) dan logika (JavaScript) . Dalam aplikasi web kecil mungkin tidak menjadi masalah, tetapi tidak peduli dengan proyek yang lebih besar. Ini jauh lebih mudah untuk mempertahankan proyek yang memisahkan struktur dan logika daripada proyek yang tidak.
  • Menghilangkan kebingungan dengan nama acara yang benar. Karena menggunakan pendengar acara inline atau menugaskan pendengar acara ke .oneventproperti elemen DOM, banyak pemrogram JavaScript yang tidak berpengalaman berpikir bahwa nama acara adalah sebagai contoh onclickatau onload. onadalah tidak bagian dari nama acara . Nama acara yang benar adalah clickdan load, dan itulah bagaimana nama acara diteruskan ke .addEventListener().
  • Bekerja di hampir semua browser . Jika Anda masih harus mendukung IE <= 8, Anda dapat menggunakan polyfill dari MDN .

element.onevent = function() {}(misalnya onclick, onload)

Contoh kode:

Ini adalah cara untuk mendaftarkan penangan acara di DOM 0. Sekarang tidak disarankan, karena:

  • Memungkinkan Anda mendaftar hanya satu pengendali acara. Juga menghapus penangan yang ditugaskan tidak intuitif, karena untuk menghapus penangan acara yang ditugaskan menggunakan metode ini, Anda harus mengembalikan oneventproperti kembali ke keadaan awal (yaitu null).
  • Tidak merespons kesalahan dengan tepat. Misalnya, jika Anda secara tidak sengaja menetapkan string 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 .
  • Tidak menyediakan cara untuk memilih jika Anda ingin menangani acara dalam fase menangkap atau menggelegak.

Penangan acara sebaris ( oneventatribut HTML)

Contoh kode:

Demikian pula untuk element.onevent, sekarang tidak disarankan. Selain masalah yang element.oneventada, itu:

  • Merupakan masalah keamanan potensial , karena membuat XSS jauh lebih berbahaya. Saat ini situs web harus mengirim Content-Security-Policytajuk HTTP yang tepat untuk memblokir skrip inline dan mengizinkan skrip eksternal hanya dari domain tepercaya. Lihat Bagaimana cara kerja Kebijakan Keamanan Konten?
  • Tidak memisahkan struktur dan logika dokumen .
  • Jika Anda membuat halaman dengan skrip sisi-server, dan misalnya Anda menghasilkan seratus tautan, masing-masing dengan penangan event inline yang sama, kode Anda akan lebih lama daripada jika penangan event didefinisikan hanya sekali. Itu berarti klien harus mengunduh lebih banyak konten, dan akibatnya situs web Anda akan lebih lambat.

Lihat juga

Michał Perłakowski
sumber
22

Saat onclickberfungsi di semua browser, addEventListenertidak bekerja di versi Internet Explorer yang lebih lama, yang digunakan attachEventsebagai gantinya.

Kelemahannya onclickadalah bahwa hanya ada satu event handler, sedangkan dua lainnya akan memecat semua callback terdaftar.

Magnar
sumber
12

Sejauh yang saya tahu, acara "memuat" DOM ​​masih bekerja dengan sangat terbatas. Itu berarti hanya akan menyala untuk window object, imagesdan <script>elemen misalnya. Hal yang sama berlaku untuk onloadpenugasan langsung . Tidak ada perbedaan teknis antara keduanya. Mungkin.onload = memiliki ketersediaan lintas-browser yang lebih baik.

Namun, Anda tidak dapat menetapkan load eventke <div>atau <span>elemen atau entah apa lagi.

jandy
sumber
9

Ringkasan:

  1. addEventListenerdapat menambahkan beberapa acara, sedangkan dengan onclickini tidak dapat dilakukan.
  2. onclickdapat ditambahkan sebagai HTMLatribut, sedangkan anaddEventListener hanya dapat ditambahkan dalam <script>elemen.
  3. addEventListener dapat mengambil argumen ketiga yang dapat menghentikan propagasi acara.

Keduanya bisa digunakan untuk menangani acara. Namun, addEventListenerharus menjadi pilihan yang disukai karena dapat melakukan segalanya onclick dan lebih banyak lagi. Jangan gunakan inline onclicksebagai atribut HTML karena ini mencampur javascript dan HTML yang merupakan praktik buruk. Itu membuat kode kurang bisa dipelihara.

Willem van der Veen
sumber
Dan bagaimana penargetan elemen kamu banyak dilakukan? Maksudku, aku secara pribadi tidak akan menggunakan inline onclickhandlrs karena takut ditertawakan keluar ruangan - tetapi biasanya peristiwa terikat jauh lebih buruk dan kurang terawat dalam beberapa tahun terakhir. Kelas suka js-link, js-form-validationatau atribut data data-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.
Christoffer Bubach
3

Satu detail belum dicatat: browser desktop modern menganggap penekanan tombol yang berbeda sebagai "klik" untuk AddEventListener('click'dan onclicksecara default.

  • Di Chrome 42 dan IE11, keduanya onclickdan AddEventListenerklik api di klik kiri dan tengah.
  • Di Firefox 38, onclickjalankan hanya pada klik kiri, tetapi AddEventListenerklik api pada klik kiri, tengah dan kanan.

Selain itu, perilaku klik tengah sangat tidak konsisten di seluruh browser saat kursor gulir terlibat:

  • Di Firefox, acara klik tengah selalu menyala.
  • Di Chrome, mereka tidak akan menyala jika middleclick membuka atau menutup kursor gulir.
  • Di IE, mereka menyala ketika kursor gulir menutup, tetapi tidak ketika itu terbuka.

Perlu juga dicatat bahwa acara "klik" untuk elemen HTML yang dapat dipilih dengan keyboard seperti inputjuga mengaktifkan ruang atau masuk saat elemen dipilih.

seorang tamu
sumber
2

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:

domElement.addEventListener // Object(Method)
domElement.attributes.onload // Object(Property(Object(Property(String))))

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:

$('[myclick]').each(function(i, v) {
     v.addEventListener('click', function() {
         eval(v.myclick); // eval($(v).attr('myclick'));
     });
});

Apa yang dilakukan JS sedikit berbeda dengan itu.

Anda dapat menyamakannya dengan sesuatu seperti (untuk setiap elemen yang dibuat):

element.addEventListener('click', function() {
    switch(typeof element.onclick) {
          case 'string':eval(element.onclick);break;
          case 'function':element.onclick();break;
     }
});

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.

jgmjgm
sumber
2

Menurut MDN , perbedaannya adalah sebagai berikut:

addEventListener:

Metode EventTarget.addEventListener () menambahkan objek yang kompatibel dengan EventListener yang ditentukan ke daftar pendengar acara untuk jenis acara yang ditentukan pada EventTarget yang disebut namanya. Target acara dapat berupa Elemen dalam dokumen, Dokumen itu sendiri, Jendela, atau objek lain yang mendukung acara (seperti XMLHttpRequest).

onclick:

Properti onclick mengembalikan kode event handler klik pada elemen saat ini. Saat menggunakan acara klik untuk memicu tindakan, pertimbangkan juga untuk menambahkan tindakan yang sama ini ke acara keydown, untuk memungkinkan penggunaan tindakan yang sama oleh orang-orang yang tidak menggunakan mouse atau layar sentuh. Sintaks element.onclick = functionRef; di mana functionRef adalah fungsi - seringkali nama fungsi yang dideklarasikan di tempat lain atau ekspresi fungsi. Lihat "Panduan JavaScript: Fungsi" untuk detailnya.

Ada juga perbedaan sintaks yang digunakan seperti yang Anda lihat dalam kode di bawah ini:

addEventListener:

// Function to change the content of t2
function modifyText() {
  var t2 = document.getElementById("t2");
  if (t2.firstChild.nodeValue == "three") {
    t2.firstChild.nodeValue = "two";
  } else {
    t2.firstChild.nodeValue = "three";
  }
}

// add event listener to table
var el = document.getElementById("outside");
el.addEventListener("click", modifyText, false);

onclick:

function initElement() {
    var p = document.getElementById("foo");
    // NOTE: showAlert(); or showAlert(param); will NOT work here.
    // Must be a reference to a function name, not a function call.
    p.onclick = showAlert;
};

function showAlert(event) {
    alert("onclick Event detected!");
}
Alireza
sumber
1

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/

/*
    Testing that the function returned from bind is rereferenceable, 
    such that it can be added and removed as an event listener.
*/
function MyImportantCalloutToYou(message, otherMessage) {
    // the following is necessary as calling bind again does 
    // not return the same function, so instead we replace the 
    // original function with the one bound to this instance
    this.swap = this.swap.bind(this); 
    this.element = document.createElement('div');
    this.element.addEventListener('click', this.swap, false);
    document.body.appendChild(this.element);
}
MyImportantCalloutToYou.prototype = {
    element: null,
    swap: function() {
        // now this function can be properly removed 
        this.element.removeEventListener('click', this.swap, false);           
    }
}

Kode di atas berfungsi baik di Chrome, dan mungkin ada beberapa shim sekitar yang membuat "bind" kompatibel dengan browser lain.

Lars Rönnbäck
sumber
1

Menggunakan penangan sebaris tidak kompatibel dengan Kebijakan Keamanan Konten sehingga addEventListenerpendekatan lebih aman dari sudut pandang itu. Tentu saja Anda dapat mengaktifkan penangan inline dengan unsafe-inlinetetapi, seperti namanya, itu tidak aman karena membawa kembali seluruh gerombolan eksploitasi JavaScript yang mencegah CSP.

kravietz
sumber
1
NB: pembatasan keamanan ini hanya berlaku untuk pengembangan ekstensi, dan justifikasi keamanan yang ditawarkan dalam dokumen tertaut sebagian besar hanya berlaku untuk pengembangan ekstensi browser. Satu hal yang dibuat dalam dokumen tertaut yang juga berlaku untuk pengembangan web pada umumnya, adalah memisahkan konten dari perilaku. Itu praktik yang baik di seluruh papan.
Chris Baker
1

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

    elm.onclick = myFunctionList
    function myFunctionList(){
      myFunc1();
      myFunc2();
    }

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 ...

patrik
sumber
1

element.onclick = function () {/ * do stuff * /}

element.addEventListener ('click', function () {/ * do stuff * /}, false);

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.

var clickEvent = document.getElementByID("onclick-eg");
var EventListener = document.getElementByID("addEventListener-eg");

clickEvent.onclick = function(){
    window.alert("1 is not called")
}
clickEvent.onclick = function(){
    window.alert("2 is not called")
}

EventListener.addEventListener("click",function(){
    window.alert("1 is called")
})
EventListener.addEventListener("click",function(){
    window.alert("2 is also called")
})
Arham Chowdhury
sumber
0

addEventListener memungkinkan Anda mengatur beberapa penangan, tetapi tidak didukung di IE8 atau lebih rendah.

IE memang punya attachEvent, tapi tidak persis sama.

pengguna113716
sumber
0

Konteks yang dirujuk oleh 'this'kata kunci di JavasSript berbeda.

lihat kode berikut:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>

</head>
<body>
    <input id="btnSubmit" type="button" value="Submit" />
    <script>
        function disable() {
            this.disabled = true;
        }
        var btnSubmit = document.getElementById('btnSubmit');
        btnSubmit.onclick = disable();
        //btnSubmit.addEventListener('click', disable, false);
    </script>
</body>
</html>

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 ke button controlbukanwindow .

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.

Larry
sumber
8
Anda perlu menulis btnSubmit.onclick = disable;(menetapkan fungsi, bukan menyebutnya). Kemudian dalam kedua kasus thisakan merujuk ke elemen tombol.
Pasha
-1

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

ThatOneNoob
sumber