绑定和事件处理程序 - 传递事件对象

7

我有一些示例代码,绑定事件处理程序的方式如下:

var h1=document.querySelector('h1');
h1.onclick=doit;

function doit(x) {
        console.log(x);
}

当事件处理程序被触发时(通过单击 h1 元素),输出结果是一个 event 对象,这是预期的。

如果我按照以下方式绑定事件处理程序:

h1.onclick=doit.bind(h1);

我得到了同样的结果。 但是,如果我按照以下方式绑定它:
h1.onclick=doit.bind(h1,1);

我得到了1,它是在h1之后的第一个参数。在所有情况下,this的值都会正确地设置为h1,但在最后一种情况下,传递的参数似乎替换了预期的事件对象。
我怎样才能在不将事件处理程序重写为函数表达式的情况下保留事件对象?

它不会替换它,而是在它之前(事件将作为第二个参数传递)。但是,如果您想要将事件放在第一个参数中,只需不部分应用函数(不要将参数绑定到它)。 - Bergi
2个回答

9

但在最后一种情况下,传递的参数似乎替换了预期的事件对象。

使用 bind 创建一个带有预先指定初始参数的函数。

MDN文档:

这些参数(如果有)跟随提供的 this 值,然后插入到传递给目标函数的参数开头,随后是每次调用绑定函数时传递给绑定函数的参数。

这意味着,如果你这样做:

h1.onclick=doit.bind(h1,1);

作为您所提到的,this的值绑定到h1,但是来自onclick的事件被作为第二个参数传递给doit,而不是第一个参数,因为您将1绑定到了第一个参数。因此,您仍然可以获得事件,它没有被替换,只是在所有绑定参数之后传递。

如何在不将事件处理程序重写为函数表达式的情况下保留事件对象?

你不能。事件将在您之前绑定到函数的所有参数之后传递,因此您必须考虑到这一点。对于给定的情况,doit应该是:

function doit(one, e) {
  console.log(this, one, e); // on click logs: h1 object, 1, event object
}

所以 doit 函数应该是类似于 doit(x,e) 这样的形式。好的,只要我不允许可选参数,否则整个函数会变得混乱。谢谢。 - Manngo
没问题,很高兴能帮忙 :) - nem035

0

如果你查看这个链接,它说第一个参数后面的参数将成为传递给函数的第一个参数。

如果你只调用h1元素,那么你所做的就是将函数绑定到该h1元素。如果你在第二个参数中传递任何其他内容,它将成为传递给函数的第一个参数。

示例

function testing(a, b, c) {
  console.log(this.property, a, b, c);
}

var obj = {
  property: 'value!'
};

var bound_test = testing.bind(obj, 'Bound Test A');
bound_test('test 1', 'checking console output');
bound_test() // should give two undefined in console since we are only giving the first object.

var bound2_test = testing.bind(obj, 'Bound test B', 'something ');
bound2_test('this will be the "c" argument');

var bound3_test = testing.bind(obj, 'Bound test C', 'Test', ' another, yet different test.');
bound3_test();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接