带有参数的 Javascript 事件处理程序

2022-08-30 05:14:17

我想做一个传递事件和一些参数的。问题是该函数不获取该元素。下面是一个示例:eventHandler

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

那呢?我似乎根本无法通过事件,我?addEventListeneraddEventListener

更新

我似乎用“这个”解决了问题

doClick = function(func){
    var that = this;
    this.element.onclick = function(e){
        func(e, that);
    }
}

其中包含我可以在函数中访问的内容。this.element

The addEventListener

但我想知道:addEventListener

function doClick(elem, func){
    element.addEventListener('click', func(event, elem), false);
}

答案 1

我不明白你的代码到底想做什么,但是你可以利用函数闭包的优势使变量在任何事件处理程序中可用:

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]))

然后,您可以使用自执行函数 (IIFE) 执行此操作,该函数在执行时捕获闭包中所需的参数并返回实际的事件处理程序函数:

element.addEventListener('click', (function(passedInElement) {
    return function(e) {func(e, passedInElement); };
}) (this.elements[i]), false);

有关 IIFE 工作原理的详细信息,请参阅以下其他参考:

在匿名函数中包装代码的 Javascript

JavaScript 中的立即调用函数表达式 (IIFE) - 传递 jQuery

JavaScript自执行匿名函数的好用例是什么?

最后一个版本可能更容易看到它正在做什么:

// 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() 向回调添加参数。传递给的任何参数都将附加到回调本身将具有的参数之前。因此,您可以执行以下操作:.bind()

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));

答案 2

这是一个古老的问题,但却是一个常见的问题。因此,让我在这里添加这个。

使用箭头函数语法,您可以更简洁地实现它,因为它是在词法上绑定并且可以链接的。

箭头函数表达式是正则函数表达式的语法紧凑替代项,尽管它没有自己的绑定到 this、参数、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'));