1

目前我正在使用 RaphealJS 库进行一个项目,在遇到这样的问题之前一切似乎都很好。

而不是多次这样做:

   dolphinIcon[1].click(function() {              
           this.attr({  
             stroke: 'black', 'stroke-width': 2,  
             fill: 'green'  
           }); 
           alert(1);
   });

   dolphinIcon[2].click(function() {              
           this.attr({  
             stroke: 'black', 'stroke-width': 2,  
             fill: 'green'  
           }); 
           alert(2);
   });

  dolphinIcon[3].click(function() {              
           this.attr({  
             stroke: 'black', 'stroke-width': 2,  
             fill: 'green'  
           }); 
           alert(3);
   });

为什么我不能这样做?

for(var i=0; i<dolphinIcon.length; i++){
     dolphinIcon[i].click(function() {              
        this.attr({  
           stroke: 'black', 'stroke-width': 2,  
           fill: 'green'  
        });      
        alert(i);
     });
}

我只希望存储在数组中的每个图标警报()其索引的数量,但是当我使用 for 循环时,无论我点击哪个图标,它总是警报()相同的数字(数组的大小) . 我应该如何解决这个问题?

4

5 回答 5

5

这是一个经典的 JavaScript 问题。每个回调函数中的变量都是相同的,一旦循环完成i,它将是相同的。dolphinIcon.length

您需要使用闭包来“捕获”i变量。

var clickFunc = function(i){
    return function(){
        this.attr({  
           stroke: 'black', 'stroke-width': 2,  
           fill: 'green'  
        });      
        alert(i);
    }
};
for(var i=0; i<dolphinIcon.length; i++){
     dolphinIcon[i].click(clickFunc(i));
}

clickFunc将返回一个对 . 的值“关闭”的函数i

您还可以将额外数据传递给click处理程序,以便在调用时使用。

for(var i=0; i<dolphinIcon.length; i++){
     dolphinIcon[i].click({i: i}, function(e) {              
        this.attr({  
           stroke: 'black', 'stroke-width': 2,  
           fill: 'green'  
        });      
        alert(e.data.i);
     });
}
于 2012-09-19T20:45:25.517 回答
3

这是因为 javascript 闭包的工作方式 - 基本上,您的回调/事件处理函数绑定到循环变量 i 而不是 i 在循环的连续迭代中的特定值。

这是简单的解决方法:只需使用匿名函数包装循环的内部,然后将循环变量传递给该函数。这将导致闭包附加到该特定值。

例如:

for(var i=0; i<dolphinIcon.length; i++)
{
    (   function(i) 
        {
            dolphinIcon[i].click(function() 
            {              
                this.attr({ stroke: 'black', 'stroke-width': 2, fill: 'green'});      
                alert(i);
            } );
        } )( i );
}
于 2012-09-19T20:46:11.607 回答
2

试试这个:

for(var i=0; i<dolphinIcon.length; i++){ 
     dolphinIcon[i].bind('click', {index: i}, function(e) {             
        $(this).attr({   
           stroke: 'black', 'stroke-width': 2,   
           fill: 'green'   
        });       
        alert(e.data.index); 
     }); 
}
于 2012-09-19T20:46:34.433 回答
0

我想推荐 underscore.js 库。它包含许多处理数组和 onbject 的实用方法(在您的情况下为每个和绑定)http://underscorejs.org/#each

在您的示例中,此代码将简化为:

_.each(dolphicons, function(dolphicon, index){  
    var func = function() {              
        this.attr({  
           stroke: 'black', 'stroke-width': 2,  
           fill: 'green'  
        });      
        console.log(index);
    }
    func = _.bind(func, dolphicon);

    dolphicon.click(func);
});

“this”将引用 dolphicon 因为绑定。示例也位于:http: //jsfiddle.net/SyJdv/

您还可以在每个循环之外限定函数

var func = function() {              
   this.obj.attr({  
      stroke: 'black', 'stroke-width': 2,  
      fill: 'green'  
    });      
    console.log(this.index);
}

_.each(dolphicons, function(dolphicon, index){  
   var clickfunc = _.bind(func, {obj: dolphicon, index: index});    
   dolphicon.click(clickfunc);
});

http://jsfiddle.net/PW9WX/1/

于 2012-09-19T21:26:14.337 回答
0

在这里,我为您提供了一个代码链接,我准备通过示例和详细信息向您解释: JavaScript for loop 三种不同的方式,单击链接阅读代码,测试自己并给个赞。

https://code.sololearn.com/WHc3WmA7TrMP

下面是代码:

<!DOCTYPE html>
<html>
   <body>

      <script type="text/javascript">
         /*
        The For Loop. Bellow are three examples using the same code in different ways, 
        returning the same results. Before let's explain which are the components fo the for loop.

        for loop have 3 components:
        1.initialization 
        2.condition
        3.Iteration 

      syntax: for (Initialization;condition;iteration)

        e.g.: for (i=1; i<=5; i++)

        In JavaScript <br> this tag is used as a line break.
        */

        //The example below creates a for loop that prints numbers 1 through 5.
        document.write("The example below creates a for loop that prints numbers 1 through 5. <br/>");
        for (i=1; i<=5; i++) {
           document.write(i + "<br />"); // <br /> is use to line break
        }

        //Statement 1 is optional, and can be omitted, if your values are set before the loop starts.
        document.write("<br/> Statement 1 is optional, and can be omitted, if your values are set before the loop starts. <br/>");
        var i = 1;
        for (; i<=5; i++) {
           document.write(i + "<br />");
        }

        //Also, you can initiate more than one value in statement 1, using commas to separate them.
        document.write("<br/> Also, you can initiate more than one value in statement 1, using commas to separate them. <br/>");
        for (i=1, text=""; i<=5; i++) {
            text = i;
            document.write(text + "<br />");
        }

        /* 
        If you notice in the for loop in JavaScript is not mandatory to declare explicitly a variable.
        e.g.: for (i=1; i<=5; i++) {}

        this is equivalent to say:
        for (var i=1; i<=5; i++) {}

        */

        // the following code will generate an infinite loop if you do not include break;
        var i = 0;
        for (; ; ) {
            document.write(i);
            i++;
            // if you comment or delete the break, this for loop will never end
            break;
        }

      </script>

      <p>Please like this code, I hope it helps you to learn more about For Loop ...</p>
   </body>
</html>
于 2017-03-08T16:36:48.090 回答