Javascript 我能通过吗;新";addEventListener的匿名函数
我使用这样的代码将参数传递给事件处理函数。但是,在这种特殊情况下,循环会导致问题。在所有activeVisual调用中,只有最后的linkTags[i]是可访问的。这与传递参数的匿名函数在整个循环中是一个相同的事实有关Javascript 我能通过吗;新";addEventListener的匿名函数,javascript,events,arguments,anonymous-function,Javascript,Events,Arguments,Anonymous Function,我使用这样的代码将参数传递给事件处理函数。但是,在这种特殊情况下,循环会导致问题。在所有activeVisual调用中,只有最后的linkTags[i]是可访问的。这与传递参数的匿名函数在整个循环中是一个相同的事实有关 for (var i = 0; i < linkTags.length; i++) { addCrossEvent(linkTags[i], "click", launchLink); addCrossEvent(linkTags[i], "moused
for (var i = 0; i < linkTags.length; i++) {
addCrossEvent(linkTags[i], "click", launchLink);
addCrossEvent(linkTags[i], "mousedown",
function(evt) {
activeVisual(evt, linkTags[i]);
});
}
for(var i=0;i
现在,我记得我尝试在匿名函数声明之前添加new,如下所示:
for (var i = 0; i < linkTags.length; i++) {
addCrossEvent(linkTags[i], "click", launchLink);
addCrossEvent(linkTags[i], "mousedown",
new function(evt) {
activeVisual(evt, linkTags[i]);
});
}
// Function that provides pass of event handling parameters with separate copy in each loop
function callbackHandler(index) {
return function(evt) {
activeVisual(evt, linkTags[index]);
}
}
...
for (var i = 0; i < linkTags.length; i++) {
...
addCrossEvent(linkTags[i], "mousedown", callbackHandler(i));
}
for(var i=0;i
它不起作用。activeVisual从未被调用。有人能给我解释一下为什么,我怎样才能让它工作吗
更新最终解决方案
感谢下面的所有回复,我的工作代码现在如下所示:
for (var i = 0; i < linkTags.length; i++) {
addCrossEvent(linkTags[i], "click", launchLink);
addCrossEvent(linkTags[i], "mousedown",
new function(evt) {
activeVisual(evt, linkTags[i]);
});
}
// Function that provides pass of event handling parameters with separate copy in each loop
function callbackHandler(index) {
return function(evt) {
activeVisual(evt, linkTags[index]);
}
}
...
for (var i = 0; i < linkTags.length; i++) {
...
addCrossEvent(linkTags[i], "mousedown", callbackHandler(i));
}
//在每个循环中提供事件处理参数传递和单独副本的函数
函数回调处理程序(索引){
返回函数(evt){
activeVisual(evt,链接标签[索引]);
}
}
...
对于(var i=0;i
您需要执行以下操作:
addCrossEvent(linkTags[i], "mousedown",
(function(i) {
return function(evt) {
activeVisual(evt, linkTags[i]);
}
)(i);
);
问题在于迭代器变量i
在每次迭代时都会发生变化,并且传递了对它的引用,i
的值不会被复制。以这种方式将其作为参数传递给包装函数,将产生一个副本,并在该特定迭代中接收实际值。您需要执行以下操作:
addCrossEvent(linkTags[i], "mousedown",
(function(i) {
return function(evt) {
activeVisual(evt, linkTags[i]);
}
)(i);
);
问题在于迭代器变量
i
在每次迭代时都会发生变化,并且传递了对它的引用,i
的值不会被复制。以这种方式将其作为参数传递给包装函数,将产生一个副本,并在该特定迭代中接收实际值。为完整起见,以下是使用new
的方法不起作用的原因说明:
当您使用new
调用函数时,该函数将生成一个空对象(您可以使用this
在函数内部引用该对象,该对象继承自函数原型)并返回它。因此,实际上您并没有将函数作为回调处理程序传递,而是传递函数返回的对象 只要对象实现了,以便可用作事件处理程序,这就不是问题。如果这样做,您可以对代码进行一些修改:
for (var i = 0; i < linkTags.length; i++) {
addCrossEvent(linkTags[i], "click", launchLink);
addCrossEvent(linkTags[i], "mousedown",
new (function(index) {
this.handleEvent = function(evt) {
activeVisual(evt, linkTags[index]);
}
})(i));
}
也就是说,我发现使用立即函数返回函数更容易阅读,而且我认为使用函数作为事件处理程序而不是对象也更常见
为了完整起见,下面解释一下为什么您使用
新
的方式不起作用:
当您使用new
调用函数时,该函数将生成一个空对象(您可以使用this
在函数内部引用该对象,该对象继承自函数原型)并返回它。因此,实际上您并没有将函数作为回调处理程序传递,而是传递函数返回的对象 只要对象实现了,以便可用作事件处理程序,这就不是问题。如果这样做,您可以对代码进行一些修改:
for (var i = 0; i < linkTags.length; i++) {
addCrossEvent(linkTags[i], "click", launchLink);
addCrossEvent(linkTags[i], "mousedown",
new (function(index) {
this.handleEvent = function(evt) {
activeVisual(evt, linkTags[index]);
}
})(i));
}
也就是说,我发现使用立即函数返回函数更容易阅读,而且我认为使用函数作为事件处理程序而不是对象也更常见
如果迭代器i变量是问题所在,那么它为什么不会在该行中引起问题addCrossEvent(linkTags[i],“click”,launchLink)?它是否仅通过引用传递给匿名函数?因为当您添加CrossEvent(linkTags[i],“click”,launchLink)时;每个循环的linkTags数组中都有值i,但当在事件上调用函数时,i有最后一个值,并且在循环中只有相同的位置array@avok00:在
addCrossEvent(linkTags[i],“click”,launchLink)
中,将linkTags[i]
的值直接传递给函数。但是activeVisual(evt,linkTags[i])回调中的code>在调用回调时计算,而不是在循环中。但是当调用回调时,循环已经完成,i
有了它的最终值。顺便说一句,您缺少一个}
来关闭立即数函数;)@avok00:它只是一个立即执行的函数(这就是为什么它看起来像(function(index){…}(i))
捕获i
的当前值(在我的示例中,在参数index
中)。请记住,函数还可以访问“更高”范围内的变量(这是闭包的原理)在这里,立即函数(事件处理程序)返回的函数可以访问“包装器”函数的作用域,因此指向索引
。您可以事先定义该函数,而不是创建即时函数,类似于我的对象示例。如果迭代器i变量是问题所在,那么它为什么不会在该行中引起问题addCrossEvent(linkTags[i],“click”,launchLink);?它是否仅通过引用传递给匿名函数?因为当您执行addCrossEvent(linkTags[i],“click”,launchLink)时,每个循环的linkTags数组中都有值i,但当在事件上调用函数时,i有最后一个值,并且在array@avok00:在addCrossEvent(链接标签[i],“单击”,启动链接)
您可以将linkTags[i]
的值直接传递给函数。但是activeVisual(evt,linkTags[i]);
在回调为cal时会对回调中的值进行评估