带参数的 Javascript 事件处理程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10000083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:25:40  来源:igfitidea点击:

Javascript event handler with parameters

javascripteventsevent-handlinghandler

提问by sebas2day

I want to make an eventHandler that passes the event and some parameters. The problem is that the function doesn't get the element. Here is an example:

我想制作一个传递事件和一些参数的 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
});

The 'elem' must be defined outside of anonymous function. How can i get the passed element to use within the anonymous function? Is there a way to do this?

'elem' 必须在匿名函数之外定义。如何让传递的元素在匿名函数中使用?有没有办法做到这一点?

And what about addEventListener? I don't seem to be able to pass the event through an addEventListener at all do I ?

那么 addEventListener 呢?我似乎根本无法通过 addEventListener 传递事件,是吗?

Update

更新

I seemed to fix the problem with 'this'

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

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

Where this contains this.element that i can access in the function.

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

The addEventListener

addEventListener

But i'm wondering about the addEventListener:

但我想知道 addEventListener:

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

回答by jfriend00

I don't understand exactly what your code is trying to do, but you can make variables available in any event handler using the advantages of function closures:

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

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

Depending upon your exact coding situation, you can pretty much always make some sort of closure preserve access to the variables for you.

根据您的确切编码情况,您几乎总是可以使某种闭包为您保留对变量的访问。

From your comments, if what you're trying to accomplish is this:

根据您的评论,如果您要完成的是:

element.addEventListener('click', func(event, this.elements[i]))

Then, you could do this with a self executing function (IIFE) that captures the arguments you want in a closure as it executes and returns the actual event handler function:

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

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

For more info on how an IIFE works, see these other references:

有关 IIFE 如何工作的更多信息,请参阅这些其他参考资料:

Javascript wrapping code inside anonymous function

匿名函数中的Javascript包装代码

Immediately-Invoked Function Expression (IIFE) In JavaScript - Passing jQuery

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

What are good use cases for JavaScript self executing anonymous functions?

JavaScript 自执行匿名函数有哪些好的用例?

This last version is perhaps easier to see what it's doing like this:

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

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


It is also possible to use .bind()to add arguments to a callback. Any arguments you pass to .bind()will be prepended to the arguments that the callback itself will have. So, you could do this:

也可以用于.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));

回答by SnnSnn

It is an old question but a common one. So let me add this one here.

这是一个古老的问题,但很常见。所以让我在这里添加这个。

With arrow function syntaxyou can achieve it more succinct way since it is lexically binded and can be chained.

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

An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords.

箭头函数表达式是正则函数表达式的一种语法紧凑的替代方案,尽管它自身没有绑定到 this、arguments、super 或 new.target 关键字。

const event_handler = (event, arg) => console.log(event, arg);
el.addEventListener('click', (event) => event_handler(event, 'An argument'));

If you need to clean up the event listener:

如果您需要清理事件侦听器:

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

Here is crazy one-liner:

这是疯狂的单线:

// You can replace console.log with some other callback function
el.addEventListener('click', (event) => ((arg) => console.log(event, arg))('An argument'));

More docile version: More appropriate for any sane work.

更温顺的版本:更适合任何理智的工作。

el.addEventListener('click', (event) => ((arg) => {
  console.log(event, arg);
})('An argument'));

回答by Knight Yoshi

Something you can try is using the bind method, I think this achieves what you were asking for. If nothing else, it's still very useful.

您可以尝试使用 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);

回答by Echsecutor

Given the update to the original question, it seems like there is trouble with the context ("this") while passing event handlers. The basics are explained e.g. here http://www.w3schools.com/js/js_function_invocation.asp

鉴于对原始问题的更新,似乎在传递事件处理程序时上下文(“this”)存在问题。基础知识在这里解释,例如 http://www.w3schools.com/js/js_function_invocation.asp

A simple working version of your example could read

您的示例的简单工作版本可以阅读

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

See also Javascript call() & apply() vs bind()?

另请参阅 Javascript call() & apply() 与 bind()?

回答by user3093134

Short answer:

简短的回答:

x.addEventListener("click", function(e){myfunction(e, param1, param2)});

... 

function myfunction(e, param1, param1) {
    ... 
} 

回答by jbabey

thisinside of doThingsis the window object. Try this instead:

this里面doThings是窗口对象。试试这个:

var doThings = function (element) {
    var eventHandler = function(ev, func){
        if (element[ev] == undefined) {
            return;
        }

        element[ev] = function(e){
            func(e, element);
        }
    };

    return {
        eventHandler: eventHandler
    };
};

回答by Δημ?τρη? Βουζουναρ??

let obj = MyObject();

elem.someEvent( function(){ obj.func(param) } );

//calls the MyObject.func, passing the param.