2012-09-19 2 views
1

현재 저는 RaphealJS 라이브러리를 사용하는 프로젝트에서 일하고 있습니다.이 같은 문제가 발생할 때까지 모든 것이 괜찮은 것처럼 보입니다. 대신이 여러 번 일을Javascript For-Loop

:

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); 
    }); 
} 
난 그냥() 인덱스의 수를 경고하기 위해 배열에 저장되어있는 각각의 아이콘을 원하는,하지만 난에 대한 루프를 사용할 때, 그것은 항상) (경고 같은 번호 (배열의 크기)

어떤 아이콘을 클릭했는지에 관계없이 이 문제를 어떻게 해결해야합니까?

답변

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

clickFunci의 값에 "폐쇄"하는 기능을 리턴한다.

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

이 대답의 가장 사본입니다 :

https://code.sololearn.com/WHc3WmA7TrMP

벨로

는 코드입니다. 나는 로켓이 전에 대답 한 것으로 의심한다.) –

+1

@KevinNielsen : 네, 이것은 일반적인 문제입니다. 나는 이것에 몇 번 대답했다. 변수로 클로저를 만드는 것을 선호합니다. 코드를 클리너로 유지할 수 있습니다. 내가 처음으로 JavaScript를 시작했을 때, 나는 똑같은 문제를 겪었습니다 :-P –

+1

오펄이했던 것과 같은 방식으로 라파엘을 처음 접하게되었습니다. 자주 사용하지 않기 때문에, 배열의 특정 항목에 대한 루프 변수의 값으로 공통 핸들러 함수를 호출하기 때문에 인라인 익명 함수를 좋아한다는 것을 배웠습니다. 그 이상으로, 당신의 기술은 확실히 깨끗합니다. –

3

이는 폐쇄 작동 자바 스크립트 방식이다.

간단한 해결 방법은 다음과 같습니다. 익명의 함수로 루프의 내부를 감싸고 해당 함수에 루프 변수를 전달하기 만하면됩니다. 그러면 클로저가 해당 특정 값에 연결됩니다. 예를 들어

:

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 때문에 참조합니다 바인딩. 당신은 내가 당신에게 내가 예와 함께 설명 할 준비 코드의 링크를 제공

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

각 루프 외부 범위를 기능에서도 연산자 수 http://jsfiddle.net/SyJdv/

:에 예에서도 연산자 세부 정보 : JavaScript for 루프는 세 가지 다른 방법으로 링크를 클릭하여 코드를 읽고 자신을 테스트하고 같은 것을 제공합니다.

<!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>