aluckdog
2023-06-09 15:02:07
我正在為 addEventListener 創建一個小的輔助類。我遇到的問題是我無法有效地同時獲得類的 this 上下文和事件的 this 上下文(附加的事件目標)。(1) 如果我使用箭頭函數,我可以獲得類的 this,但我無法獲得綁定的 this(通過 Function.prototype.call)(2) 如果我使用函數表達式,我可以得到綁定的this,但是我不能訪問類。(3) 我也不能使用內部封閉。必須從外部范圍引用函數/方法。這是一個簡化的例子,向您展示我的意思。有沒有辦法勾選所有方框?我所能想到的就是創建另一個幫助程序類,該類將為附加的每個事件偵聽器進行初始化,但是如果有更簡單的方法,那似乎效率不高。class EventListenerHelper { private targets: Array<EventTarget> constructor() { // If there was a single target, it would be very easy. But there are multiple this.targets = [ document.body, window ]; } /** * (1) - Try to use an arrow function * * This falls short because it's not possible to get the this context of the Event */ private attachWithArrowFunction() { this.targets.forEach((target) => { target.addEventListener('click', this.listenerCallbackArrow, false); }); } private listenerCallbackArrow = (e: Event) => { // Cannot get event this const eventThis = undefined; // Note that e.target is the innermost element which got hit with the event // We are looking for that target that had the event listener attached // If I'm not mistaken, the only way to get it is from the this context // which is bound to the event callback this.processListener(eventThis, e); } /** * (2) - Try to use a regular class method * * This falls short because it's not possible to get the this context of the class */ private attachWithClassMethod() { this.targets.forEach((target) => { target.addEventListener('click', this.listenerCallbackMethod, false); }); } private listenerCallbackMethod(e: Event) { // Here we have the eventThis const eventThis = this; // But the class instance is completely unreachable }
1 回答

臨摹微笑
TA貢獻1982條經驗 獲得超2個贊
一種常見的處理方法是返回一個函數:
private attach() {
const listener = this.getListener()
this.targets.forEach(target => {
target.addEventListener('click', listener, false)
})
}
private getListener() {
const self = this
return function (e: Event) {
// self if EventListenerHelper this
// this is Event this
}
}
但我看不出它有多大好處,因為this在你傳遞給的函數內部addEventListener等于event.currentTarget,所以你可以只綁定你的監聽器并使用屬性而不是this:
constructor() {
// ...
this.listener = this.listener.bind(this)
}
private listener(e) {
// this is EventListenerHelper this
// e.currentTarget is Event this
}
添加回答
舉報
0/150
提交
取消