2012-09-19 245 views
1

目前我正在使用RaphealJS庫,一切都項目似乎直到我遇到了一個問題,像這樣的好起來。的Javascript for循環

而是多次執行此操作的:

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循環,它時刻警惕()相同數量(數組的大小)無論我點擊哪個圖標。我應該如何解決這個問題?

回答

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

這就是答案的最好的副本。我懷疑火箭已經回答了=) –

+1

@凱文尼爾森:是的,這是一個常見問題。我已經回答了幾次。我更喜歡把閉包變成一個變量,它可以讓你的代碼更清潔。當我第一次開始使用JavaScript時,我遇到了同樣的問題:-P –

+1

當我進入Raphael時,我第一次遇到了Opal所做的同樣的事情。我學會了愛內聯匿名函數,因爲通常不會,我只想用數組中的特定項的循環變量的值調用常用處理函數。除此之外,你的技術當然更清潔。 –

3

這是因爲JavaScript閉合的工作方式 - 基本上,你的回調/事件處理功能結合到循環變量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); 
} 
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); 
    }); 
} 
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); 
}); 

「這」指的dolphicon因爲綁定。 例如alsoo在:http://jsfiddle.net/SyJdv/

你可以alsoo範圍功能的每個循環

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/

0

在這裏我爲大家提供的代碼的鏈接,我準備用實例和解釋你外面有關詳細信息:以三種不同方式使用JavaScript進行循環,單擊鏈接讀取代碼,測試自己並給出相似的結果。

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>