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

IT技术 javascript html dom-events
2021-02-04 00:10:44

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

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方法中的第二个参数传入据我所知,我只能使用没有括号的函数名。

任何的想法?

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

4个回答

无需传入任何内容。用于的函数addEventListener将自动this绑定到当前元素。只需this在您的函数中使用

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/


如果你想设置的值this手动,您可以使用call方法来调用该函数:

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);
}
在您的第二个示例中,您稍后将如何删除该事件侦听器?该函数是匿名的。
2021-03-14 00:10:44
伟大的!完美的答案!您能否指出将函数名称(我的意思是不带括号)传递给其他函数的javascript机制是什么?这对我来说真的很有趣
2021-03-27 00:10:44
在第二个示例中,我喜欢通过将参数包装在匿名函数中来将参数传递给函数的想法,但是还有其他方法可以做到这一点吗?类似于 OP 在他的问题中发布的内容?
2021-03-29 00:10:44
无价的答案。
2021-04-04 00:10:44

在 JS 代码的第一行:

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

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


这种情况下addEventListener调用的函数中,forthis将自动设置为侦听器附加到的对象productLineSelect

如果这就是你想要的,你可以只传递函数引用,并且this在这个例子中是select从 addEventListener 调用的:

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

如果这不是您想要的,那么您最好bind将此值用于传递给的函数addEventListener

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

.bind部分也是一个调用,但这个调用只返回我们正在调用的同一个函数bindthis该函数范围内的值固定thisArg,有效地覆盖了 this-binding 的动态特性。


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

您将不得不使用额外的函数定义:

var globalVar = 'global';

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

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


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

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

productLineSelect.addEventListener('change', function(event) {
    var localVar = 'local';
    getSelection(event, this, globalVar, localVar);
}.bind(thisArg), false);
谢谢 Jeffrey Westerkamp,您的回答很有帮助,因为您详细解释了它!
2021-03-15 00:10:44

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

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

如果this您想要值只是您将事件处理程序绑定到的对象,那么addEventListener()已经为您完成了。当你这样做时:

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

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

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.