2013-03-12 124 views
0

我正在循环一个对象数组,并且遇到奇怪的行为。这里是我的代码:为什么数组的最后一个元素只能在Javascript中使用onClick

window.onload = function() { 

    document.getElementById('btnAdd').onclick = function() { 
     add("button"); 
    }; 
    function add(type) { 
     var names = {}; 
     names['one'] = { id: "Button 1",msg:"#1" }; 
     names['two'] = { id: "Button 2", msg: "#2" }; 
     names['three'] = { id: "Button 3", msg: "#3" }; 
     //Create an input type dynamically. 
     function addOnClick(element, currentName) { 
       element.onClick = function() { 
       alert("button is " + names[currentName].msg); 
      }; 
      };  

     for (name in names) { 
      var element = document.createElement("input"); 

      element.type = type; 
      element.value = names[name].id; 
      element.name = name; 
      addOnClick(element,name); 

      var foo = document.getElementById("fooBar"); 
      //Append the element in page (in span). 
      foo.appendChild(element); 
     } 
    } 
}; 

继承人的HTML:

<p> 
<input type="button" id="btnAdd" value="Add Buttons" /> 
<p id="fooBar">Buttons: </p> 

</p> 

如果您在浏览器中运行它,并“添加按钮”按钮,3个按钮创建并适当命名。但是,如果你点击3个新按钮中的一个,警告框总是说“按钮是#3”,我不知道为什么。有人可以解释为什么onClick事件只记住我的数组中的最后一项?谢谢

+0

为什么不让你的名字对象数组? – 2013-03-12 17:32:49

+0

我试过了,但我得到了同样的结果,所以我省略了它。 – BoundForGlory 2013-03-12 17:34:04

+0

它'element.onclick'不''element.onClick' – mrk 2013-03-12 18:01:50

回答

3

你陷入了JavaScript中的封闭捕获规则。只有name的一个副本,并且当onclick发射时,它将是集合names中最后的name值。为了解决这个问题,你需要创建一个新的function范围,捕捉name

var addOnClick = function(currentName) { 
    element.onclick = function() { 
    alert("button is " + names[currentName].msg); 
    }; 
}; 
addOnClick(name); 

编辑的当前值

你还需要使用onclickonClick。在此情况下,重要的

小提琴:http://jsfiddle.net/Nzf3p/

+0

感谢您的回复。我更新了上面的代码,但没有弹出窗口。 – BoundForGlory 2013-03-12 17:55:06

+0

@ user1202717你也有'onclick'与'onClick'的问题。我更新了我的答案,并链接到一个小提琴 – JaredPar 2013-03-12 18:01:12

+0

真棒..非常感谢你 – BoundForGlory 2013-03-12 18:02:50

2

这是由于在Javascript(局部变量捕获)受封的工作方式。分配给element.onclick匿名函数是:

function() { 
    // Note this is a function 
    alert("button is "+ names[name].msg); 
}; 

这里,name值被绑定到的环,这是最后一个元素中遇到的最后一个值。循环中的name本质上指向外循环中由name使用的内存位置。该位置不断更新,最后指向值three。为了解决这个问题,你需要一个额外的功能(创建一个新的范围)来保存name的值。这将创建一个版本的name是局部的新功能,因此保留:

//A self-invoked function, into which you pass name. preservedName is the preserved 
//value of name, which is local to the scope of this self-invoked function. 
(function(preservedName) { 
    element.onclick = function() { 
     alert("button is " + names[preservedName].msg); 
    }; 
})(name); 
1

的问题是由于关闭你创建的onclick处理程序。

element.onclick = function() { // Note this is a function 
      alert("button is "+ names[name].msg); 
     }; 

应该由一个通过了名字你感兴趣的一个函数来包装:

addOnClickToElement(element,name); 

然后在相同的范围内的“添加”,这样names是可访问的添加此命名函数:

function addOnClickToElement(element,name) { // Note this is a function 
    element.onclick = function(){alert("button is "+ names[name].msg);}; 
} 
+0

感谢您的答复。我很接近但并不完全。我更新了我的代码 – BoundForGlory 2013-03-12 17:51:10

+0

我评论了你的问题,但我也会在这里做 - 它是'element.onclick'而不是'element.onClick' – mrk 2013-03-12 18:02:52

相关问题