66

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

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

4 回答 4

134

不需要传入任何东西。用于的函数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);
}
于 2012-08-19T05:45:16.970 回答
13

在您的 JS 代码的第一行:

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

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


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

如果这是您想要的,您可以只传递函数引用,并且this在此示例中将在selectaddEventListener 的调用中:

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

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

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

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


要解决您的实际问题:“如何将参数传递给 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);
于 2017-01-12T22:29:39.060 回答
7

使用时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);
}
于 2012-08-19T06:04:32.977 回答
3

如果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
于 2012-08-19T06:01:25.777 回答