2013-05-06 3 views
0

내가 다음 코드Javascript에서 클로저를 사용할 때 mouseover 이벤트가 작동하지 않는 이유는 무엇입니까?

<ul> 
    <li>one</li> 
    <li>two</li>   
    <li>three</li> 
    <li>four</li> 
</ul> 

var lists = document.getElementsByTagName("li"); 

for(var i=0, len = lists.length; i< len; i++){ 
    lists[i].onmouseover = function(){ 
     console.log(i); 
    }(i); 
} 

예상 결과 : 마우스가 각 li을 통해, 내가 콘솔에 0 또는 1, 2 또는 3을 가지고 있지만 mouseover에서 페이지를 새로 고칠 때 난 단지 그 수를 받았을 때, 아무도 왜 그런지 압니까?

답변

3

함수 즉시을 실행하고 (undefined이다) 이벤트 핸들러로서 반환 값을 할당 함수식 이후 "발신 괄호"(i).

function foo(i) { 
    console.log(i); 
} 

// in the loop 
lists[i].onmouseover = foo(i); 

를 호출하는 방법을 foo 확인하고 반환 값이 lists[i].onmouseover에 할당 : 여기에 쉽게 (희망)를 참조 할 수 있습니다 함수 선언과 예입니다?

당신은 즉시 호출 함수 표현식에서 함수를 반환해야 :

lists[i].onmouseover = (function(i){ 
    return function() { 
     console.log(i); 
    }; 
}(i)); 

또는 함수 선언 :

function createHandler(i) { 
    return function() { 
     console.log(i); 
    }; 
} 

// in the loop 
lists[i].onmouseover = createHandler(i); 

상세 정보 : JavaScript closure inside loops – simple practical example

+0

는 return 문이 필요합니까? 다음과 같이 할 수 있습니다 : 'code' (function (index) { ) [index] .onmouseover = function() { console.log (i); }; }) (i);'code' 죄송합니다. , 나는 코멘트에 코드를 형식화하는 방법을 모르겠다. – user2301368

+0

네, 그렇게 할 수 있습니다. 즉시 실행 된 기능을 "한 단계 위"로 이동해야합니다. 그것은 아무것도 변경하지 않지만, 그것은 여전히 ​​같은 방식으로 작동합니다. –

+0

대단히 감사합니다, Felix Kling, 귀하의 답변이 매우 자세합니다. 귀하의 요지가 있습니다. – user2301368

관련 문제