如何将参数传递给 addEventListener 侦听器函数?

IT技术 javascript dom addeventlistener
2021-01-16 07:05:10

情况有点像——

var someVar = some_other_function();
someObj.addEventListener("click", function(){
    some_function(someVar);
}, false);

问题是 的值someVar在 的侦听器函数内不可见addEventListener,它可能被视为新变量。

6个回答

为什么不直接从事件的目标属性中获取参数?

例子:

const someInput = document.querySelector('button');
someInput.addEventListener('click', myFunc, false);
someInput.myParam = 'This is my parameter';
function myFunc(evt)
{
  window.alert(evt.currentTarget.myParam);
}
<button class="input">Show parameter</button>

JavaScript 是一种面向原型的语言,记住!

这是正确的答案,因为它让我们在 'removeEventListener' 函数之后使用。
2021-03-22 07:05:10
我的变量总是以未定义的形式返回……关于如何解决这个问题的任何想法?
2021-03-24 07:05:10
如果addEventListener是 for documentevt.target.myParam对我不起作用。我不得不evt.currentTarget.myParam改用。
2021-03-24 07:05:10
这样保存this在typescript中使用此方法需要元素成为any或创建子类型。
2021-03-25 07:05:10
不应该evt.currentTarget.myParam吗?如果在“someInput”中有另一个元素,则evt.target可能是指内部元素。( jsfiddle.net/qp5zguay/1 )
2021-04-02 07:05:10

你写的代码绝对没有问题。双方some_functionsomeVar应访问的,以防他们在上下文中可用的匿名

function() { some_function(someVar); } 

被创建。

检查警报是否为您提供了您一直在寻找的值,确保它可以在匿名函数的范围内访问(除非您有更多代码someVar对调用旁边的同一变量进行操作addEventListener

var someVar; 
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click", function(){
    some_function(someVar);
}, false);
有谁知道为什么它不能循环工作?这种行为的原因是什么?
2021-03-21 07:05:10
@Morfidon:在循环中, someVar 的值不是添加侦听器时的值,而是执行侦听器时的值。当监听器被执行时,循环已经结束,所以 someVar 的值将是它在循环结束时的值。
2021-03-22 07:05:10
这在 for 循环中不起作用。我总是得到最新的值,而不是属于那个迭代的值。有什么解决办法吗?
2021-03-30 07:05:10
这不是正确的答案,因为它不允许我们在之后使用“removeEventListener”函数。
2021-04-02 07:05:10
@iMatoria 我刚刚发现创建bound function使用该.bind()方法将解决循环问题developer.mozilla.org/en/docs/Web/JavaScript/Reference/...
2021-04-08 07:05:10

这个问题很老,但我想我会提供一个使用 ES5 的替代方案.bind()- 为后代。:)

function some_func(otherFunc, ev) {
    // magic happens
}
someObj.addEventListener("click", some_func.bind(null, some_other_func), false);

请注意,您需要使用第一个参数设置侦听器函数作为传递给 bind(您的其他函数)的参数,第二个参数现在是事件(而不是第一个,因为它本来是) .

Function.prototype.bind()确实是解决这个问题的最好方法。此外,它在循环内直观地工作——你得到你想要的词法范围。没有匿名函数、IIFE或附加到对象的特殊属性。
2021-03-10 07:05:10
通过使用Function.prototype.bind()您不能删除事件侦听器,最好改用柯里化函数(请参阅@tomcek112 答案)
2021-03-12 07:05:10
查看IIFE 与 bind() 的优缺点
2021-03-13 07:05:10
注意:some_other_func是一个变量,你可以传递任何你想要的值some_func
2021-03-17 07:05:10

相当古老的问题,但我今天遇到了同样的问题。我发现的最干净的解决方案是使用柯里化的概念

代码:

someObj.addEventListener('click', some_function(someVar));

var some_function = function(someVar) {
    return function curried_func(e) {
        // do something here
    }
}

通过命名柯里化函数,它允许您调用 Object.removeEventListener 以在以后执行时取消注册 eventListener。

我不喜欢为了删除监听器而必须命名柯里化函数的想法,因为然后你要处理 2 个你必须跟踪的 diff 命名空间
2021-03-29 07:05:10
看到好的术语真是太棒了。您应该能够通过命名柯里化函数来删除事件侦听器。我会提出一个编辑。
2021-03-31 07:05:10
此答案将注册函数的次数与调用 addEventListener 的次数相同,因为 some_function (var) 每次都返回一个新创建的函数。
2021-04-01 07:05:10
很高兴遇到这个提到咖喱函数的答案。但是,您将如何删除事件侦听器?
2021-04-06 07:05:10
@martin36 注意durrying 结构,你有一个currying function和一个curried function您应该添加和删除柯里化函数作为事件侦听器。在@tomeck112 的例子中,就是some_function
2021-04-07 07:05:10

您可以使用 'bind' 绑定所有必要的参数:

root.addEventListener('click', myPrettyHandler.bind(null, event, arg1, ... ));

通过这种方式,你将永远得到eventarg1传递,和其他的东西myPrettyHandler

http://passy.svbtle.com/partial-application-in-javascript-using-bind

谢谢!已经尝试过.bind()但没有 null 作为第一个参数。这没有用。
2021-03-25 07:05:10
不需要null,它适用于.bind(event, arg1),至少适用于 VueJS。
2021-03-30 07:05:10