将多个参数与事件对象一起传递给事件处理程序

8

如何在不使用 Function.prototype.bind 的情况下将多个参数与事件对象一起传递给事件处理程序?

事件处理程序内部存在一个闭包。

以下基本代码无法正常工作,

element.addEventListener("click", eventHandler(eventObj + arguments), false);

function eventHandler(eventObj + arguments) {
  return function(){}; //a closure
}

我不知道如何同时传递事件对象和其他参数给事件处理程序。

更新:

我甚至尝试在addEventListener中使用匿名函数。但这样做似乎控制流永远无法到达回调函数内部的闭包。

element.addEventListener("click", function(e){
    var data = {'event':e, 'args':arguments};
    eventHandler(data);
  }, false);

function eventHandler(data) {
  return function(){  //this function is never executed
    console.log(JSON.stringify(data));
  };
}
5个回答

27

如果我理解正确,您想向元素添加事件监听器,并在添加监听器时配置一些附加数据,以便在调用监听器时传递这些数据。如果这就是您想要做的,您只需要一个合适的闭包。假设您想将附加数据存储在对象中,则可以按照以下方式实现:

var extra_data = {one: "One", two: "Two"};

var make_handler = function (extra_data) {
  return function (event) {
    // event and extra_data will be available here
  };
};

element.addEventListener("click", make_handler(extra_data));

1
你怎么移除这个事件监听器?我试过 element.removeEventListener("click", make_handler(extra_data)); 但是它没有被移除。 - crimson_king
我也试图移除这个事件监听器,但是没有成功。 - Sanlyn

2
我怀疑你不行,但是有一个技巧:

我怀疑您不能这样做,但有一个技巧:

element.clickArguments=new Object();
element.clickArguments.argument1=...;
element.clickArguments.argument2=...;

现在在您的事件处理程序中引用事件发射对象。

很棒的解决方案...省去了我制作自定义事件的麻烦。谢谢! - lauCosma

1

辅助函数:

function curryRight( original ) {
    var args = [].slice.call( arguments, 1 );
    return function() {
        return original.apply( this, [].slice.call( arguments ).concat( args ) );
    };
}

使用方法:

element.addEventListener("click", curryRight( eventHandler, 1, 2, 3 ), false );

例子:

function eventHandler( event, a, b, c ) {
    console.log( event, a, b, c );
    //Logs MouseEvent, 1, 2, 3
}

document.addEventListener("click", curryRight( eventHandler, 1, 2, 3 ), false );

1

我知道这个帖子已经很旧了,但这是我在这里经常看到的一个常见错误。

我甚至尝试在addEventListener内部使用匿名函数。 这样做,似乎控件永远不会到达回调函数内部的闭包。
--
@asur

你需要从eventHandler()中调用返回的闭包。

element.addEventListener("click", function(e){
    var data = {'event':e, 'args':arguments};
    eventHandler(data)();    // invoking the closure here
  }, false);

如果你不这样做,只会得到一个闭包返回到二进制的涅槃。

除此之外,与@jmm的解决方案相比,它更加简洁,因此更受欢迎。


0

我有一个函数,其中有一个参数用于捕获当前相对URL以及其他值。为了简单起见,我只提到URL的参数。

在这里使用“event”作为关键字,可以捕获事件对象:

function Analyze(url) {
if (event) {
// do something with the event object, such as:
alert(event.timeStamp);
// ...
}

该函数在一个按钮中被调用

onclick="Analyze(document.URL);".

是的,我知道这种调用方式让我看起来像个顽皮的孩子,但在这种情况下有一个很好的借口。

如果将"event"替换为"e"或"x",则此技术无法工作,但可能会有其他可能性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接