JavaScript回调函数中的变量总是在循环中获得最后一个值? [英] Variable in JavaScript callback functions always gets last value in loop?

查看:156
本文介绍了JavaScript回调函数中的变量总是在循环中获得最后一个值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试执行以下操作:

I'm trying to do the following:

我有一组图像和选择(下拉列表)HTML元素,每个元素30个。我正在尝试在1到30的循环上使用AddEventListener,这样当我更改select的值时,图像src会更新(并且图像会更改)。

I have a set of images and select (dropdown) HTML elements, 30 of each one. I'm trying to use AddEventListener on a loop from 1 to 30 so that when I change the value of the select, the image src is updated (and the image changes).

AddEventListener函数是这样的:

The AddEventListener function is this one:

function AddEventListener(element, eventType, handler, capture)
{
    if (element.addEventListener)
        element.addEventListener(eventType, handler, capture);
    else if (element.attachEvent)
        element.attachEvent("on" + eventType, handler);
}

我试过这个并且有效:

var urlfolderanimalimages = "http://localhost/animalimages/";
var testselect = "sel15";
var testimg = "i15";

AddEventListener(document.getElementById(testselect), "change", function(e) {
    document.getElementById(testimg).src = urlfolderanimalimages + document.getElementById(testselect).value;
    document.getElementById(testimg).style.display = 'inline';

    if (e.preventDefault) e.preventDefault();
    else e.returnResult = false;
    if (e.stopPropagation) e.stopPropagation();
    else e.cancelBubble = true;
}, false);

但是我试图在循环中调用它并且它不起作用。该事件已添加,但当我更改任何选择时,它将更新最后一个(ID为i30的图像)。

But then I tried to call it in a loop and it doesn't work. The event is added, but when I change any select, it will update the last one (the image with id i30).

var urlfolderanimalimages = "http://localhost/animalimages/";

for (k=1;k<=30;k++) {
    var idselect = "sel" + k;
    var idimage = "i" + k;

    AddEventListener(document.getElementById(idselect), "change", function(e) {
        document.getElementById(idimage).src = urlfolderanimalimages + document.getElementById(idselect).value;
        document.getElementById(idimage).style.display = 'inline';

        if (e.preventDefault) e.preventDefault();
        else e.returnResult = false;
        if (e.stopPropagation) e.stopPropagation();
        else e.cancelBubble = true;
    }, false);

}

我做错了什么?我是JavaScript(和一般编程)的新手,对于引起呕吐的代码很抱歉:(

What am I doing wrong? I'm new to JavaScript (and programming in general), so sorry for the vomit-inducing code :(

推荐答案

问题是你正在关闭相同的变量

var不会声明变量 1 。它只是为给定执行上下文中的标识符注释停止查找。

var does not declare a variable1. It simply annotates a 'stop look-up' for an identifier within a given execution context.

请参阅 Javascript ClosuresFAQ Notes,包含所有不错的细节。关于执行上下文和范围链的部分是最多的有趣的。

Please see Javascript Closures "FAQ Notes" for all the nice details. The sections on 'execution context' and 'scope chain' are most interesting.

常见的习惯用法是执行双重绑定来创建新的执行上下文。

The common idiom is perform a double-binding to create a new execution context.

Eg

var k
for (k = 1; k < 10; k++) {
  setTimeout((function (_k) {
    return function () {
      alert(_k)
    }
  })(k), k * 100)
}






从JavaScript第5版开始, Function.bind (它也可以在第3版中实现,例如 bind from prototype.js ),可以这样使用:


As of JavaScript 5th Edition there is Function.bind (it can also be implemented in 3rd edition such as bind from prototype.js), which can be used as such:

var k
for (k = 1; k < 10; k++) {
  setTimeout((function () {
     alert(this)
  }).bind(k), k * 100)
}






1 此构造在ECMAScript规范中称为变量声明。然而,这一陈述,正如可能被视为误导,强调要带回家:还可以看到变量提升。


1 This construct is referred to as a Variable Declaration in the ECMAScript specification. However, this statements, as misleading as it may be viewed, is stressed to bring home a point: also see "variable hoisting".

这篇关于JavaScript回调函数中的变量总是在循环中获得最后一个值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆