Javascript concept for variable scope
本问题已经有最佳答案,请猛点这里访问。
我有5个按钮,我不能更改DOM,不能使用id和name属性,不能使用innerHTML,现在我需要输出,就像我点击按钮1它应该给出一个警告,如"你点击按钮#1"和相同 将继续所有5个按钮。 我想打印i的值。现在我遇到了两个解决方案:
HTML部分:
1 2 3 4 5 6 | //creating 5 buttons <button>one</button> <button>two</button> <button>three</button> <button>four</button> <button>five</button> |
第一解决方案
1 2 3 4 5 6 7 8 | /* here I am always having you clicked element #5*/ var nodes = document.getElementsByTagName('button');//getting references var counter; for (var i = 0; i < nodes.length; i++) { nodes[i].addEventListener('click', function() { alert('You clicked element #' + i); }); } //which is not working |
第二解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /* here I am getting correct output*/ var nodes = document.getElementsByTagName('button'); var counter; for (var i = 0; i < nodes.length; i++) { assignEvent(nodes[i], i); } function assignEvent(node, i){ node.addEventListener('click', function(){ alert('You clicked element#' + (i+1)); }); }//this one is working |
现在我的问题是为什么解决方案2正在工作,但解决方案1没有..请帮助。 为什么解决方案2正确地承载了i的值,而不是解决方案1。
你可以这样写:
1 2 3 4 5 6 | [].forEach.call(document.getElementsByTagName('button'), function(elt, index) { elt.addEventListener('click', function() { alert('You clicked element #' + (index + 1)); }, false); }); |
如果您不想创建其他函数,只需将事件侦听器赋值包装在您传递给'i'的自调用匿名函数中:
1 2 3 4 5 6 7 8 9 | var nodes = document.getElementsByTagName('button'); var counter; for (var i = 0; i < nodes.length; i++) { (function(j) { nodes[i].addEventListener('click', function() { alert('You clicked element #' + (j+1)); }); })(i); } |
jsfiddle在这里:http://jsfiddle.net/vu31aa7y/
在您的第一个解决方案中,当您添加匿名函数作为addEventListener的参数时,警报消息正在查找i的最后一个值,在这种情况下i = 5,这是因为您在函数中没有变量为local,所以 如果全局变量,你唯一可能的值。
如果你想这样做试试这个:
1 2 3 4 5 6 7 8 9 | var nodes = document.getElementsByTagName('button');//getting references function alertMessage(i){ alert('You clicked element#' + (i+1)); } for (i = 0; i < nodes.length; i++) { nodes[i].addEventListener('click', alertMessage.bind(null,i) , false); } |
我也推荐你这个讲座