[英]Javascript event handler with parameters
我想制作一個eventHandler
事件和一些參數的事件處理程序。 問題是 function 沒有獲取元素。 這是一個例子:
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
必須在匿名 function 之外定義。如何讓傳遞的元素在匿名 function 中使用? 有沒有辦法做到這一點?
那addEventListener
呢? 我似乎根本無法通過addEventListener
傳遞事件,對嗎?
更新
我似乎用“這個”解決了問題
doClick = function(func){
var that = this;
this.element.onclick = function(e){
func(e, that);
}
}
其中包含我可以在this.element
中訪問的 this.element。
添加事件監聽器
但我想知道addEventListener
:
function doClick(elem, func){
element.addEventListener('click', func(event, elem), false);
}
我不明白你的代碼到底想做什么,但你可以利用 function 閉包的優勢使變量在任何事件處理程序中可用:
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);
}
根據您的具體編碼情況,您幾乎總是可以讓某種閉包為您保留對變量的訪問。
根據您的評論,如果您要完成的是:
element.addEventListener('click', func(event, this.elements[i]))
然后,您可以使用自執行 function (IIFE) 執行此操作,它在閉包執行時捕獲您想要的 arguments 並返回實際事件處理程序 function:
element.addEventListener('click', (function(passedInElement) {
return function(e) {func(e, passedInElement); };
}) (this.elements[i]), false);
有關 IIFE 如何工作的更多信息,請參閱以下其他參考資料:
立即調用 Function 表達式 (IIFE) 在 JavaScript - 傳遞 jQuery
最后一個版本可能更容易看到它在做什么:
// 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]));
也可以使用.bind()
將 arguments 添加到回調中。 您傳遞給.bind()
的任何 arguments 都將添加到回調本身將具有的 arguments 之前。 所以,你可以這樣做:
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));
這是一個古老的問題,但卻是一個普遍的問題。 所以讓我在這里添加這個。
使用箭頭 function 語法,您可以更簡潔地實現它,因為它是詞法綁定的並且可以鏈接。
箭頭 function 表達式是常規 function 表達式的語法緊湊替代方案,盡管它自己沒有綁定到 this、arguments、super 或 new.target 關鍵字。
const event_handler = (event, arg) => console.log(event, arg);
el.addEventListener('click', (event) => event_handler(event, 'An argument'));
如果您需要清理事件偵聽器:
// 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);
這是瘋狂的一行:
// You can replace console.log with some other callback function
el.addEventListener('click', (event) => ((arg) => console.log(event, arg))('An argument'));
更溫順的版本:更適合任何理智的工作。
el.addEventListener('click', (event) => ((arg) => {
console.log(event, arg);
})('An argument'));
您可以嘗試使用 bind 方法,我認為這可以實現您的要求。 如果不出意外,它仍然非常有用。
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);
鑒於對原始問題的更新,似乎在傳遞事件處理程序時上下文(“this”)出現問題。 基礎知識在這里解釋http://www.w3schools.com/js/js_function_invocation.asp
你的例子的一個簡單的工作版本可以閱讀
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);
簡短回答:
x.addEventListener("click", function(e){myfunction(e, param1, param2)});
...
function myfunction(e, param1, param1) {
...
}
嘗試,
const handleOnChange = (event, otherParameter) => {
console.log(`${event.target.value}`);
console.log(`${otherParameter}`);
}
<Select onchange= (event) => {
handleOnChange(event, otherParameter);
}>
this
的內部是doThings
object。試試這個:
var doThings = function (element) {
var eventHandler = function(ev, func){
if (element[ev] == undefined) {
return;
}
element[ev] = function(e){
func(e, element);
}
};
return {
eventHandler: eventHandler
};
};
這是一個老話題,@jfriend00 做了非常好的工作,解釋了閉包 function 調用背后的基礎知識。
讓我們將代碼片段更新為 ES6,並使用另一種可能幫助我們克服這種情況的技術。
首先讓我們定義一個 function handler
,此 function 將接收兩個參數fnc
和val
,其中fnc
是將處理事件的自定義 function 通常是 names on
+ theEventName
在這種情況下onClickEvent
。 這里沒有什么新鮮事。 現在讓我們在元素red
上定義onclick
偵聽器,它將像這樣調用clickEventHandler
:
red.onclick = clickEventHandler
正如我們注意到clickEventHandler
沒有任何參數Teo,我如何將event
和index
值發送到處理程序?
好問題,首先讓我們調用handler
function 來創建我們的自定義onClickEvent
處理程序,如下所示:
handler(onClickEvent, index)
但是 Teo, onClickEvent
也沒有參數,我們如何發送閉包 function onClickEvent
, onclick
產生的event
和index
值?
耐心等待我年輕的學徒。 首先哪個 function 將處理該event
? 在我們的場景中將是onClickEvent
所以讓我們定義這個 function 來接收event
e
和index
值v
:
function onClickEvent(e, v) {
console.log(`${e.currentTarget.className} -> [x: ${e.x}, y: ${e.y}] | val: ${v}`)
}
現在讓我們實現我們的處理程序 function。這個 function 將返回一個閉包 function 定義,它將執行在fnc
中定義的 function,還將合並閉包 function 接收的參數和val
參數,如下所示:
function handler(fnc, val) {
return (...params) => {
const ctx = this
const arg = [...params, val]
fnc.apply(ctx, arg)
}
}
我們使用apply()
來調用fnc
。 此方法使用給定的上下文ctx
調用指定的 function,並將arg
作為數組提供的 arguments。 因此, fnc
使用閉包 function 上下文ctx
執行。
這是此場景的工作片段。
const red = document.querySelector('.red') const blue = document.querySelector('.blue') function handler(fnc, val) { return (...params) => { const ctx = this const arg = [...params, val] fnc.apply(ctx, arg) } } function onClickEvent(e, v) { console.log(`${e.currentTarget.className} -> [x: ${ex}, y: ${ey}] | val: ${v}`) } const index = 50 // Define the handler function const clickEventHandler = handler(onClickEvent, index) // Call the debounced function on every mouse move red.onclick = clickEventHandler blue.addEventListener('click', clickEventHandler)
.boxes { width: 100%; height: 120px; display: flex; flex-flow: row nowrap; }.red { background: red; }.blue { background: blue; }.box { width: 50%; display: flex; justify-content: center; align-items: center; color: white; }
<div class='boxes'> <div class='red box'>Click Me</div> <div class='blue box'>Not ready</div> </div>
現在讓我們將這個概念應用到您的場景中:
const red = document.querySelector('.red') const blue = document.querySelector('.blue') red.clicked = false let clickEventHandler function handler(fnc, val) { return (...params) => { const ctx = this const arg = [...params, val] fnc.apply(ctx, arg) } } function onRedClickEvent(e) { if (red.clicked) return red.clicked = true red.textContent = 'Clicked' blue.textContent = 'Ready' console.log(`${e.currentTarget.className} -> blue is ready`) // Define the handler function clickEventHandler = handler(onClickEvent, red) // Call the debounced function on every mouse move blue.addEventListener('click', clickEventHandler) } function onClickEvent(e, elem) { red.clicked = false red.textContent = 'Click Me' blue.textContent = 'Not Ready' console.log(`${e.currentTarget.className} -> [x: ${ex}, y: ${ey}] | elem: ${elem.className}`) blue.removeEventListener('click', clickEventHandler) } red.onclick = onRedClickEvent
.boxes { width: 100%; height: 120px; display: flex; flex-flow: row nowrap; }.red { background: red; }.blue { background: blue; }.box { width: 50%; display: flex; justify-content: center; align-items: center; color: white; user-select: none; }
<div class='boxes'> <div class='red box'>Click Me</div> <div class='blue box'>Not ready</div> </div>
let obj = MyObject();
elem.someEvent( function(){ obj.func(param) } );
//calls the MyObject.func, passing the param.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.