Saya ingin membuat eventHandler yang meneruskan event dan beberapa parameter. Masalahnya adalah fungsinya tidak mendapatkan elemen. Berikut ini contohnya:
doClick = function(func){
var elem = .. // the element where it is all about
elem.onclick = function(e){
func(e, elem);
}
}
doClick(function(e, element){
// do stuff with element and the event
});
'Elem' harus ditentukan di luar fungsi anonim. Bagaimana saya bisa mendapatkan elemen yang diteruskan untuk digunakan dalam fungsi anonim? Apakah ada cara untuk melakukan ini?
Dan bagaimana dengan addEventListener? Saya sepertinya tidak bisa melewatkan acara melalui addEventListener sama sekali, bukan?
Memperbarui
Sepertinya saya memperbaiki masalah dengan 'ini'
doClick = function(func){
var that = this;
this.element.onclick = function(e){
func(e, that);
}
}
Dimana ini berisi this.element yang bisa saya akses dalam fungsinya.
AddEventListener
Tapi saya bertanya-tanya tentang addEventListener:
function doClick(elem, func){
element.addEventListener('click', func(event, elem), false);
}
javascript
events
event-handling
handler
sebas2day
sumber
sumber
e.target
/e.currentTarget
?Jawaban:
Saya tidak mengerti persis apa yang coba dilakukan kode Anda, tetapi Anda dapat membuat variabel tersedia di semua event handler menggunakan keuntungan dari penutupan fungsi:
function addClickHandler(elem, arg1, arg2) { elem.addEventListener('click', function(e) { // in the event handler function here, you can directly refer // to arg1 and arg2 from the parent function arguments }, false); }
Bergantung pada situasi pengkodean Anda yang tepat, Anda selalu dapat membuat semacam penutupan untuk mempertahankan akses ke variabel untuk Anda.
Dari komentar Anda, jika yang ingin Anda capai adalah ini:
element.addEventListener('click', func(event, this.elements[i]))
Kemudian, Anda dapat melakukan ini dengan fungsi eksekusi mandiri (IIFE) yang menangkap argumen yang Anda inginkan dalam closure saat ia mengeksekusi dan mengembalikan fungsi penanganan kejadian yang sebenarnya:
element.addEventListener('click', (function(passedInElement) { return function(e) {func(e, passedInElement); }; }) (this.elements[i]), false);
Untuk info lebih lanjut tentang cara kerja IIFE, lihat referensi lain ini:
Kode pembungkus Javascript di dalam fungsi anonim
Ekspresi Fungsi (IIFE) yang Segera Diminta Dalam JavaScript - Meneruskan jQuery
Apa kasus penggunaan yang baik untuk JavaScript yang menjalankan sendiri fungsi anonim?
Versi terakhir ini mungkin lebih mudah untuk melihat apa yang dilakukannya seperti ini:
// return our event handler while capturing an argument in the closure function handleEvent(passedInElement) { return function(e) { func(e, passedInElement); }; } element.addEventListener('click', handleEvent(this.elements[i]));
Bisa juga digunakan
.bind()
untuk menambahkan argumen ke callback. Argumen apa pun yang Anda teruskan.bind()
akan ditambahkan ke argumen yang akan dimiliki oleh callback itu sendiri. Jadi, Anda bisa melakukan ini:elem.addEventListener('click', function(a1, a2, e) { // inside the event handler, you have access to both your arguments // and the event object that the event handler passes }.bind(elem, arg1, arg2));
sumber
element.addEventListener('click', func(event, this.elements[i]))
. Javascript tidak berfungsi seperti itu. Ada cara lain untuk menyiasatinya, menggunakan closure, tetapi Anda tidak bisa melakukannya seperti yang Anda tulis. addEventListener memanggil callbacknya dengan tepat satu argumen (peristiwa) dan Anda tidak dapat mengubahnya dengan cara apa pun.function eventFunction (arg, evt) { console.log(arg[0],arg[1],arg[2]) console.log(evt) } var el = document.getElementById('elementID'); el.addEventListener('click', eventFunction.bind(el,[1,2,3]))
Perhatikan bahwa argumen event selalu terakhir dalam argumen untuk fungsi tersebut, dan tidak secara eksplisit dideklarasikan dalam metode bind.Ini adalah pertanyaan lama tapi pertanyaan umum. Jadi izinkan saya menambahkan yang ini di sini.
Dengan sintaks fungsi panah Anda dapat mencapainya dengan cara yang lebih ringkas karena secara leksikal terikat dan dapat dirantai.
Ekspresi fungsi panah adalah alternatif yang secara sintaksis ringkas untuk ekspresi fungsi reguler, meskipun tanpa ikatannya sendiri ke kata kunci this, arguments, super, atau new.target.
const event_handler = (event, arg) => console.log(event, arg); el.addEventListener('click', (event) => event_handler(event, 'An argument'));
Jika Anda perlu membersihkan pendengar acara:
// Let's use use good old function sytax function event_handler(event, arg) { console.log(event, arg); } // Assign the listener callback to a variable var doClick = (event) => event_handler(event, 'An argument'); el.addEventListener('click', doClick); // Do some work... // Then later in the code, clean up el.removeEventListener('click', doClick);
Ini satu kalimat gila:
// You can replace console.log with some other callback function el.addEventListener('click', (event) => ((arg) => console.log(event, arg))('An argument'));
Versi yang lebih jinak : Lebih sesuai untuk pekerjaan yang waras.
el.addEventListener('click', (event) => ((arg) => { console.log(event, arg); })('An argument'));
sumber
this
dan pawang dapat mengakses apa yang dibutuhkannya.Sesuatu yang dapat Anda coba adalah menggunakan metode mengikat, saya pikir ini mencapai apa yang Anda minta. Jika tidak ada yang lain, itu masih sangat berguna.
function doClick(elem, func) { var diffElem = document.getElementById('some_element'); //could be the same or different element than the element in the doClick argument diffElem.addEventListener('click', func.bind(diffElem, elem)) } function clickEvent(elem, evt) { console.log(this); console.log(elem); // 'this' and elem can be the same thing if the first parameter // of the bind method is the element the event is being attached to from the argument passed to doClick console.log(evt); } var elem = document.getElementById('elem_to_do_stuff_with'); doClick(elem, clickEvent);
sumber
Mengingat pembaruan untuk pertanyaan asli, sepertinya ada masalah dengan konteks ("ini") saat melewati penangan kejadian. Dasar-dasarnya dijelaskan misalnya di sini http://www.w3schools.com/js/js_function_invocation.asp
Versi kerja sederhana dari contoh Anda bisa dibaca
var doClick = function(event, additionalParameter){ // do stuff with event and this being the triggering event and caller } element.addEventListener('click', function(event) { var additionalParameter = ...; doClick.call(this, event, additionalParameter ); }, false);
Lihat juga Javascript call () & apply () vs bind ()?
sumber
Jawaban singkat:
x.addEventListener("click", function(e){myfunction(e, param1, param2)}); ... function myfunction(e, param1, param1) { ... }
sumber
param1
atauparam2
. Jika nilai-nilai itu berubah, mereka tidak akan disetel ke nilai yang semula saat pengendali kejadian dibuat. Mereka akan disetel ke nilai saat ini saja. Selain itu, ini tidak berbeda dengan menyetel variabel di luar cakupan fungsi event listener dan mereferensikan variabel tersebut di event handler, sehingga tidak menyelesaikan penerusan parameter sama sekali.param1
adalahnoodle
pertama kalinya addEventListener disebut, dan kedua kalinya Anda menyebutnya,param
adalahcheese
maka kapan saja pendengar acaraclick
kebakaran,param1
akan diatur kecheese
dan tidaknoodle
. Oleh karena itu, ia tidak menggunakan "closure" untuk mengingat nilai yang ada pada saat event listener ditambahkan. Ada skenario di mana pendengar acara harus ditambahkan beberapa kali yang tidak perlu diilustrasikan agar poin saya valid.this
di dalamdoThings
adalah objek jendela. Coba ini sebagai gantinya:var doThings = function (element) { var eventHandler = function(ev, func){ if (element[ev] == undefined) { return; } element[ev] = function(e){ func(e, element); } }; return { eventHandler: eventHandler }; };
sumber
let obj = MyObject(); elem.someEvent( function(){ obj.func(param) } ); //calls the MyObject.func, passing the param.
sumber