2009-11-22 7 views
4

div를 클릭하면 div 1을 클릭하면 '1'로 표시되고 div 2를 클릭하면 '5'가 표시됩니다. 훨씬 더 큰 응용 프로그램에서이 코드가 필요하기 때문에이 코드를 가능한 한 쉽게 만들려고했습니다.addEventListener의 Javascript 변수 범위 익명 함수

<html> 
<head> 
<style type="text/css"> 
#div1 { background-color: #00ff00; margin: 10px; padding: 10px; } 
#div2 { background-color: #0000ff; margin: 10px; padding: 10px; } 
</style> 
<script type="text/javascript"> 

function init() 
{ 
    var total = 1; 

    var div1 = document.getElementById('div1'), 
     div2 = document.getElementById('div2'); 

    var helper = function(event, id) 
    { 
     if (event.stopPropagation) event.stopPropagation(); 
     if (event.preventDefault) event.preventDefault(); 

     alert('id='+id); 
    } 

    div1.addEventListener('click', function(event) { helper(event, total); }, false); 

    total += 4; 

    div2.addEventListener('click', function(event) { helper(event, total); }, false); 

} 

</script> 
</head> 

<body onload="init();"> 

<div id="div1">1</div> 
<div id="div2">2</div> 

</body> 
</html> 

도움 주셔서 감사합니다. :-)

답변

8

문제는 이벤트 리스너 및 '전체'가 동일한 범위에 존재한다는 것이다 (INIT())

이벤트 함수는 항상 초기화() 범위 내에서 총을 참조하려는, 심지어 함수가 선언 된 후에 변경된 경우

이 문제를 해결하려면 이벤트 함수가 변경되지 않는 자체 범위에 '합계'가 있어야합니다. 사용자는 예를 들어 익명 함수

을 사용 범위의 계층을 추가 할 수

(function (total) { 
    div1.addEventListener('click', function(event) { helper(event, total); }, false); 
}(total)); 

total += 4; 

(function (total) { 
    div2.addEventListener('click', function(event) { helper(event, total); }, false); 
}(total)); 

익명 함수 파라미터로 초기화()의 현재 '전체'의 값을 전달한다. 이것은 익명 함수의 범위에 또 다른 '합계'를 설정합니다. 따라서 init()의 총 변경 여부는 중요하지 않습니다. 이벤트 함수가 익명 함수의 범위를 먼저 참조하기 때문입니다.

편집 :

이 또한 그렇지 않으면 스크립트가 '이벤트'정의되지 않은 것을 불평, 헬퍼 함수의 닫는 중괄호 뒤에 세미콜론을 배치해야합니다.

var helper = function(event, id) 
{ 
    if (event.stopPropagation) event.stopPropagation(); 
    if (event.preventDefault) event.preventDefault(); 

    alert('id='+id); 
}; 
+0

아. 그래서 효과적으로 C++ 변수 *에서와 같이 total이 가변 포인터처럼되어 가고 있습니까? –

+0

사실, 로컬 범위로 복사됩니다. 그것이 포인터라면, 스코프 내부와 외부에서 바뀌어 원래의 문제로 되돌아 갈 것입니다. – Matt

+2

@Gary Matt의 예는 정확합니다. 여기에 약간의 용어가 있습니다. JavaScript의 강력하고 강력한 기능인 "클로저"(http://www.jibbering.com/faq/faq_notes/closures.html)로 인해 특정 문제가 발생했습니다. 매트가 당신에게 보여 주었던 것은 익명의 함수와 currying으로 알려진 기법을 사용하여 클로저 속성 (때로는 사용자가 보았 듯이)에 접근하는 방법입니다. http://ejohn.org/blog/partial-functions-in-javascript/ 및 http://stackoverflow.com/questions/1413916/을 참조하십시오. –

2

이 거의 동일하지만 난 그게 더 좋을 것이라고 생각 :

div1.addEventListener('click', function(t){ return function(event) { helper(event, t); }}(total), false); 

대신 :

(function (total) { 
    div2.addEventListener('click', function(event) { helper(event, total); }, false); 
}(total));