如何在addEventListener中使用将参数传递给函数?

How to pass parameter to function using in addEventListener?

提问人:mko 提问时间:8/19/2012 最后编辑:Brian Tompsett - 汤莱恩mko 更新时间:3/2/2021 访问量:139728

问:

以传统方式添加事件侦听器:

function getComboA(sel) {
    var value = sel.options[sel.selectedIndex].value;  
}

<select id="comboA" onchange="getComboA(this)">
<option value="">Select combo</option>
<option value="Value1">Text1</option>
<option value="Value2">Text2</option>
<option value="Value3">Text3</option>
</select>

但我想适应这种方式:addEventListener

productLineSelect.addEventListener('change',getSelection(this),false);

function getSelection(sel){
    var value = sel.options[sel.selectedIndex].value;
    alert(value);
}

它不起作用,因为我无法将任何参数作为方法中的第二个参数传递?据我所知,我只能使用不带括号的函数名称。getSelection()addEventListener

有什么想法吗?

顺便说一句,请看我之前关于在 Safari 6.0 Developer Inspector 中不起作用的问题,我无法在控制台中编写任何输出,这令人沮丧。console.log

JavaScript HTML DOM 事件

评论

0赞 Michał Perłakowski 1/13/2017
Pass an extra argument to a callback function 的可能重复项

答:

145赞 Joseph Silber 8/19/2012 #1

无需传递任何东西。用于的函数将自动绑定到当前元素。只需在您的函数中使用:addEventListenerthisthis

productLineSelect.addEventListener('change', getSelection, false);

function getSelection() {
    var value = this.options[this.selectedIndex].value;
    alert(value);
}

这是小提琴:http://jsfiddle.net/dJ4Wm/


如果要将任意数据传递给函数,请将其包装在自己的匿名函数调用中:

productLineSelect.addEventListener('change', function() {
    foo('bar');
}, false);

function foo(message) {
    alert(message);
}

这是小提琴:http://jsfiddle.net/t4Gun/


如果要手动设置 的值,可以使用 call 方法调用函数:this

var self = this;
productLineSelect.addEventListener('change', function() {
    getSelection.call(self);
    // This'll set the `this` value inside of `getSelection` to `self`
}, false);

function getSelection() {
    var value = this.options[this.selectedIndex].value;
    alert(value);
}

评论

1赞 mko 8/19/2012
伟大!完美的答案!您能指出哪种 javascript 机制将函数名称(我的意思是没有括号)传递给其他函数吗?这对我来说真的很有意思
3赞 kta 12/7/2016
无价的答案。
8赞 jkupczak 6/21/2017
在第二个示例中,稍后将如何删除该事件侦听器?该函数是匿名的。
0赞 Praneet Dixit 11/18/2020
在第二个示例中,我喜欢通过将参数包装在匿名函数中来将参数传递给函数的想法,但是还有其他方法可以做到这一点吗?就像 OP 在他的问题中发布的内容一样?
3赞 jfriend00 8/19/2012 #2

如果所需的值只是将事件处理程序绑定到的对象,则已经为您执行了该操作。执行此操作时:thisaddEventListener()

productLineSelect.addEventListener('change', getSelection, false);

该函数将已调用,并将 set 设置为事件处理程序绑定到的对象。它还将被传递一个表示事件对象的参数,该对象具有有关事件的各种对象信息。getSelectionthis

function getSelection(event) {
    // this will be set to the object that the event handler was bound to
    // event is all the detailed information about the event
}

如果所需的值不是将事件处理程序绑定到的对象,则可以执行以下操作:this

var self = this;
productLineSelect.addEventListener('change',function() {
    getSelection(self)
},false);

通过解释:

  1. 将 的值保存到其他事件处理程序中的局部变量中。this
  2. 然后,创建一个匿名函数来传递 addEventListener。
  3. 在该匿名函数中,调用实际函数并向其传递保存的值 。this
7赞 Lee 8/19/2012 #3

当您使用 时,将自动绑定。因此,如果要引用安装事件处理程序的元素,只需在函数中使用:addEventListenerthisthis

productLineSelect.addEventListener('change',getSelection,false);

function getSelection(){
    var value = sel.options[this.selectedIndex].value;
    alert(value);
}

如果要从调用的上下文中传入一些其他参数,则可以使用闭包,如下所示:addEventListener

productLineSelect.addEventListener('change', function(){ 
    // pass in `this` (the element), and someOtherVar
    getSelection(this, someOtherVar); 
},false);

function getSelection(sel, someOtherVar){
    var value = sel.options[sel.selectedIndex].value;
    alert(value);
    alert(someOtherVar);
}
15赞 JJWesterkamp 1/13/2017 #4

在 JS 代码的第一行中:

select.addEventListener('change', getSelection(this), false);

通过放置在函数引用后面来调用 getSelection。这很可能不是您想要的,因为您现在将该调用的返回值传递给 addEventListener,而不是对实际函数本身的引用。(this)


在本例中,由 for 调用的值将自动设置为侦听器附加到的对象。addEventListenerthisproductLineSelect

如果这是你想要的,你可以只传递函数引用,在这个例子中,它将在addEventListener的调用中:thisselect

select.addEventListener('change', getSelection, false);

如果这不是你想要的,你最好将你的值绑定到你要传递给的函数:addEventListener

var thisArg = { custom: 'object' };
select.addEventListener('change', getSelection.bind(thisArg), false);

该部分也是一个调用,但此调用仅返回我们正在调用的相同函数,该函数范围内的值固定为 ,有效地覆盖了此绑定的动态性质。.bindbindthisthisArg


要解决您的实际问题:“如何在 addEventListener 中传递参数以函数?

您必须使用其他函数定义:

var globalVar = 'global';

productLineSelect.addEventListener('change', function(event) {
    var localVar = 'local';
    getSelection(event, this, globalVar, localVar);
}, false);

现在,我们将事件对象、对 addEventListener 回调中值的引用、在该回调中定义和初始化的变量以及整个 addEventListener 调用外部的变量传递给您自己的函数。thisgetSelection


我们也可能再次选择在外部回调中放置一个对象:this

var thisArg = { custom: 'object' };
var globalVar = 'global';

productLineSelect.addEventListener('change', function(event) {
    var localVar = 'local';
    getSelection(event, this, globalVar, localVar);
}.bind(thisArg), false);

评论

1赞 Yone 1/24/2018
谢谢Jeffrey Westerkamp,你的回答很有帮助,你详细解释了!
0赞 pietervanderstar 6/30/2023
这个答案似乎是最好的,但可以通过提及创建绑定版本创建“新”函数来改进。将其保存在变量中并传递该函数还将允许使用 removeEventListener。有关更多信息@bens请参阅此处的 aswer:stackoverflow.com/questions/11565471/...