2012-01-16 3 views
1

for 루프를 사용하여 divs 일련의 이벤트에 click 이벤트를 추가하려고했습니다. divs은 동적으로 작성되어로드됩니다. 모든 div는 자체 콜백 함수를 호출해야합니다. 그러나 모든 div가 최종 이벤트 리스너에 연결되어 있고 최종 이벤트 리스너의 콜백 함수를 호출하는 것 같습니다. 클릭에새 노드에 이벤트 추가

for(index=0; index<divs.length; index++) { 
    divs[index].addEventListener("click", function(){console.log(divs[index].getAttribute("id"));}, true); //capture click event 
} 

는 최종 DIV의 ID가 모든 사업부가 표시됩니다

다음은 내 기본 코드입니다.

+0

자바 스크립트 클로저에 대해 읽고 코드를 편집하십시오. 변수 범위 문제입니다. – DhruvPathak

답변

8

Phil's answer은 (+1) 게시 한 코드 코드에 대한 좋은 해결책을 제공하지만 문제가 원래 코드와 어떤 관계가 있는지 설명하지 않습니다.

문제는 이벤트 핸들러 폐쇄가 index 변수를 참조를 지속 얻을 수 있다는 것입니다 아닌 그들이 생성 할 때의로의를 복사합니다. 따라서 그들은 모두 index에()의 최종 값을 표시합니다. 시간 제한이 발생할 때, 예를 들면,이 코드

for (index = 0; index < 4; ++index) { 
    setTimeout(function() { 
     console.log(index); 
    }, 100); 
} 

는 없다 ... "0", "1", "2"및 "3", "4"네 번 기록한다.

일반적인 값으로 핸들러가 특정 값으로 닫히는 지 확인하려면 이벤트 핸들러 함수를 생성하는 팩토리 함수를 사용하십시오. 여기서 이벤트 핸들러는 팩토리에 제공하는 인수를 닫습니다 대신 루프 변수의 기능 :

for(index=0; index<divs.length; index++) { 
    divs[index].addEventListener("click", createHandler(divs[index], true); //capture click event 
} 

function createHandler(div) { 
    return function(){ 
     console.log(div.getAttribute("id")); 
    }; 
} 

이 이벤트 핸들러는 변경되지 않습니다 div 위에 닫습니다.

클로저는 JavaScript의 가장 강력한 기능 중 하나입니다.그들이 어떻게 작동하는지 이해하면 (실제로 사람들이 생각하는 것보다 훨씬 간단합니다), 정말로 좋은 효과를 내기 위해 사용할 수 있습니다. 기타 : Closures are not complicated

+0

+1 큰 문제 설명 . 귀하의'createHandler' 메쏘드는 IE (<9)'attachEvent'에서도 작동 할 것입니다. 반면에 광산은 지원하지 않습니다 ('this' 지원이 깨졌습니다) – Phil

+0

@ T.J. 클로저 폐쇄가 재미 있습니다, 고맙습니다. –

3

이것은 루프가 완료된 후 마지막 요소로 설정된 이벤트 처리기에서 divs[index]을 사용하고 있기 때문입니다.

대신 this을 사용하십시오. 참조 또한, 예를 들어, 대신 동일한 폐쇄의 무리를 만드는

function logId(e) { 
    console.log(this.getAttribute("id")); 
} 

... 그리고 루프에 ...

divs[index].addEventListener("click", logId, false); 

을 하나 개의 이벤트 핸들러를 사용할 수 있습니다 https://developer.mozilla.org/en/DOM/element.addEventListener#Memory_issues

+0

+1 '이'를 사용하는 것이 좋습니다. –

+0

@Phil, 고맙습니다,이게 도움이 되네 –

2

당신 @phil에 의해 지적 된대로 this 키워드를 사용할 수 있습니다.

그러나이 폐쇄를 고려, 문제가 무엇인지 설명하기 :
for(index=0; index<divs.length; index++) { 
    (function(index){ 
     divs[index].addEventListener("click", function(){ 
      console.log(divs[index].getAttribute("id")); 
     }, true); 
    })(index); 
} 

지금, 모든 기능의에게 index 변수의 자체 사본을 얻을. 코드에서 모두 동일한 변수를 공유합니다. 따라서 결국 indexdiv이 실제로 클릭되는 것과 관계없이 divs.length -1과 같을 것입니다.

+0

일러스트레이션도 잘 돌아가지만, 여전히 도움이되는 것은 무엇입니까 (function (arg) {statement}) (arg), 고맙습니다. –

관련 문제