关于jquery:变量范围的Javascript概念

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);
        }

我也推荐你这个讲座