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

Abh*_*dav 275 javascript dom addeventlistener

情况有点像 -

var someVar = some_other_function();
someObj.addEventListener("click", function(){
    some_function(someVar);
}, false);
Run Code Online (Sandbox Code Playgroud)

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

小智 319

为什么不从事件的target属性中获取参数?

例:

var someInput = document.querySelector('input');
someInput.addEventListener('click', myFunc, false);
someInput.myParam = 'This is my parameter';
function myFunc(evt)
{
  window.alert(evt.currentTarget.myParam);
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这是正确的答案,因为它让我们在'removeEventListener'函数之后使用. (14认同)
  • 不应该是`evt.currentTarget.myParam`?如果'someInput'中有另一个元素,`evt.target`可以引用内部元素.(https://jsfiddle.net/qp5zguay/1/) (14认同)
  • 应该被选为接受的答案 - 这是最干净最好的方式! (6认同)
  • 我最喜欢这个答案!应该是正确的答案. (4认同)
  • 我的变量不断返回为未定义...关于如何解决这个问题有什么想法吗? (3认同)
  • 如果“addEventListener”用于“document”,则“evt.target.myParam”对我不起作用。我不得不使用 `evt.currentTarget.myParam` 来代替。 (2认同)
  • 不建议向 DOMElement 添加自定义/附加属性 (2认同)

Ser*_*sky 189

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

function() { some_function(someVar); } 
Run Code Online (Sandbox Code Playgroud)

创建了.

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

var someVar; 
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click", function(){
    some_function(someVar);
}, false);
Run Code Online (Sandbox Code Playgroud)

  • 这在for循环中不起作用.我总是得到最新的价值,而不是那个属于那次迭代的价值.有解决方案吗 (75认同)
  • @Morfidon:在循环中,someVar的值不是添加侦听器时的值,而是执行侦听器时的值.执行监听器时,循环已经结束,因此someVar的值将是循环结束时的值. (12认同)
  • 有谁知道为什么它不能在循环中工作?这种行为的原因是什么? (5认同)
  • @iMatoria我刚刚发现使用`.bind()`方法创建一个`bound函数`将解决循环问题https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/功能/绑定 (4认同)
  • @Morfidon因为带有全局变量的函数在javascript中充当[闭包](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures),这意味着它们会记住其词法范围之外的环境.如果您只是在相同的环境中创建不同的功能,那么它们将引用相同的环境. (3认同)
  • 这不是正确的答案因为它不允许我们使用'removeEventListener'函数之后. (3认同)

Bri*_*ore 55

这个问题已经过时了,但我认为我会提供另一种使用ES5的.bind() - 替代后代.:)

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

请注意,你需要设置你的侦听器函数,第一个param作为你传递给bind的参数(你的另一个函数),第二个param现在是事件(而不是第一个,就像它本来的那样) .

  • 通过使用`Function.prototype.bind()`你不能[删除事件监听器](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener),最好使用而是使用柯里化函数(参见 @tomcek112 答案) (5认同)
  • [Function.prototype.bind()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind)确实是解决这个问题的最佳方法。另外,它在循环内直观地工作——您可以获得所需的词法范围。没有匿名函数、[IIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE) 或附加到对象上的特殊属性。 (4认同)

Ole*_*nko 26

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

root.addEventListener('click', myPrettyHandler.bind(null, event, arg1, ... ));
Run Code Online (Sandbox Code Playgroud)

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

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


小智 23

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

代码:

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

var some_function = function(someVar) {
    return function curried_func(e) {
        // do something here
    }
}
Run Code Online (Sandbox Code Playgroud)

通过命名curried函数,它允许您调用Object.removeEventListener以在稍后的执行时取消注册eventListener.

  • 很高兴遇到这个提到咖喱功能的答案.你会如何删除事件监听器? (4认同)
  • 很高兴看到好的术语.您应该能够通过命名curried函数来删除事件侦听器.我会建议编辑. (3认同)
  • 这个答案将在调用 addEventListener 时多次注册该函数,因为 some_function (var) 每次都会返回一个新创建的函数。 (2认同)
  • 我不喜欢必须命名柯里化函数才能删除侦听器的想法,因为然后你要处理你必须跟踪的 2 个差异命名空间 (2认同)
  • @martin36 请注意持续结构,你有一个“柯里化函数”和一个“柯里化函数”。您应该添加和删除柯里化函数作为事件侦听器。在@tomeck112的示例中,即“some_function” (2认同)

小智 18

您可以通过将函数声明为变量来添加和删除带参数的eventlisteners.

myaudio.addEventListener('ended',funcName=function(){newSrc(myaudio)},false);

newSrc是myaudio作为参数的方法 funcName是函数名变量

您可以删除侦听器 myaudio.removeEventListener('ended',func,false);

  • 使用 `myaudio.removeEventListener('end',funcName,false);` funcName not func 删除侦听器:) 我无法编辑您的帖子,因为编辑必须至少有 6 个字符... (2认同)

小智 14

不错的单线替代品

element.addEventListener('dragstart',(evt) => onDragStart(param1, param2, param3, evt));
Run Code Online (Sandbox Code Playgroud)
function onDragStart(param1, param2, param3, evt) {

 //some action...

}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案的问题是,如果您需要它,它不允许您使用“removeEventListener”...... (14认同)
  • @purple_turtle,我使用 JS 已有 8 年多了,我仍然发现这个答案对我最有帮助。 (3认同)

ahu*_*igo 11

你可以通过一个名为closure的javascript函数按值传递somevar(而不是通过引用):

var someVar='origin';
func = function(v){
    console.log(v);
}
document.addEventListener('click',function(someVar){
   return function(){func(someVar)}
}(someVar));
someVar='changed'
Run Code Online (Sandbox Code Playgroud)

或者您可以编写一个常见的包装函数,例如wrapEventCallback:

function wrapEventCallback(callback){
    var args = Array.prototype.slice.call(arguments, 1);
    return function(e){
        callback.apply(this, args)
    }
}
var someVar='origin';
func = function(v){
    console.log(v);
}
document.addEventListener('click',wrapEventCallback(func,someVar))
someVar='changed'
Run Code Online (Sandbox Code Playgroud)

wrapEventCallback(func,var1,var2)就像:

func.bind(null, var1,var2)
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢您的回答!OP 并不是在寻找这个,但我认为在谷歌中输入“如何将参数传递给 addEventListener”的人将会寻找你的答案。它只需要更多的解释:)我正在编辑它。 (3认同)

小智 11

一种简单的执行方法可能是这样的

    window.addEventListener('click', (e) => functionHandler(e, ...args));
Run Code Online (Sandbox Code Playgroud)

对我有用。


The*_*evs 9

someVar值只能在some_function()上下文中访问,而不能从侦听器访问.如果你想在监听器中使用它,你必须做以下事情:

someObj.addEventListener("click",
                         function(){
                             var newVar = someVar;
                             some_function(someVar);
                         },
                         false);
Run Code Online (Sandbox Code Playgroud)

newVar改为使用.

另一种方法是返回someVarsome_function()以便在侦听器中进一步使用它(作为新的局部变量):

var someVar = some_function(someVar);
Run Code Online (Sandbox Code Playgroud)


Hel*_*rld 9

这是另一种方式(这个在for循环中工作):

var someVar = some_other_function();
someObj.addEventListener("click", 

function(theVar){
    return function(){some_function(theVar)};
}(someVar),

false);
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的方法.丑陋但在循环内有效,因为通过向匿名函数发送参数将捕获var. (2认同)

小智 8

Function.prototype.bind()是将目标函数绑定到特定作用域并有选择地this在目标函数内定义对象的方法。

someObj.addEventListener("click", some_function.bind(this), false);
Run Code Online (Sandbox Code Playgroud)

或捕获某些词汇范围,例如在循环中:

someObj.addEventListener("click", some_function.bind(this, arg1, arg2), false);
Run Code Online (Sandbox Code Playgroud)

最后,如果this目标函数中不需要该参数:

someObj.addEventListener("click", some_function.bind(null, arg1, arg2), false);
Run Code Online (Sandbox Code Playgroud)


kta*_*kta 7

使用

   el.addEventListener('click',
    function(){
        // this will give you the id value 
        alert(this.id);    
    },
false);
Run Code Online (Sandbox Code Playgroud)

如果你想将任何自定义值传递给这个匿名函数,那么最简单的方法就是

 // this will dynamically create property a property
 // you can create anything like el.<your  variable>
 el.myvalue = "hello world";
 el.addEventListener('click',
    function(){
        //this will show you the myvalue 
        alert(el.myvalue);
        // this will give you the id value 
        alert(this.id);    
    },
false);
Run Code Online (Sandbox Code Playgroud)

在我的项目中完美运作.希望这会有所帮助


小智 5

一种方法是使用外部函数来执行此操作:

elem.addEventListener('click', (function(numCopy) {
  return function() {
    alert(numCopy)
  };
})(num));
Run Code Online (Sandbox Code Playgroud)

这种将匿名函数括在括号中并立即调用它的方法称为 IIFE 立即调用函数表达式)

您可以在http://codepen.io/froucher/pen/BoWwgz中查看带有两个参数的示例。

catimg.addEventListener('click', (function(c, i){
  return function() {
    c.meows++;
    i.textContent = c.name + '\'s meows are: ' + c.meows;
  }
})(cat, catmeows));
Run Code Online (Sandbox Code Playgroud)


dev*_*r82 5

如果我没有记错的话,使用调用函数bind实际上会创建一个由该bind方法返回的新函数。这会在以后给你带来问题,或者如果你想删除事件监听器,因为它基本上就像一个匿名函数:

// Possible:
function myCallback() { /* code here */ }
someObject.addEventListener('event', myCallback);
someObject.removeEventListener('event', myCallback);

// Not Possible:
function myCallback() { /* code here */ }
someObject.addEventListener('event', function() { myCallback });
someObject.removeEventListener('event', /* can't remove anonymous function */);
Run Code Online (Sandbox Code Playgroud)

所以请记住这一点。

如果您使用的是 ES6,您可以按照建议的方式进行操作,但会更简洁一些:

someObject.addEventListener('event', () => myCallback(params));
Run Code Online (Sandbox Code Playgroud)


cho*_*ovy 5

    $form.addEventListener('submit', save.bind(null, data, keyword, $name.value, myStemComment));
    function save(data, keyword, name, comment, event) {
Run Code Online (Sandbox Code Playgroud)

这就是我正确通过事件的方式。


hoo*_*ogw 5

2019 年,很多 api 发生了变化,最佳答案不再有效,没有修复 bug。

分享一些工作代码。

受到上述所有答案的启发。

 button_element = document.getElementById('your-button')

 button_element.setAttribute('your-parameter-name',your-parameter-value);

 button_element.addEventListener('click', your_function);


 function your_function(event)
   {
      //when click print the parameter value 
      console.log(event.currentTarget.attributes.your-parameter-name.value;)
   }
Run Code Online (Sandbox Code Playgroud)