2009-11-22 107 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())

事件功能總是要在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()的當前‘合計’的值作爲參數。這爲匿名函數的作用域設置了另一個「全部」,所以init()的總體變化與否,無關緊要,因爲事件函數將首先引用匿名函數的作用域。

編輯:

此外,您還需要放置一個分號的輔助函數的右括號之後,否則該腳本會抱怨說,「事件」是不確定的。

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

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

啊。所以有效的總體變得像變量指針,就像在C++變量*? – 2009-11-22 21:03:19

+0

實際上,它被複制到本地範圍。如果它是一個指針,那麼它會在範圍內和範圍之外改變,這會使你回到原來的問題。 – Matt 2009-11-22 21:34:19

+2

@加里馬特的例子是正確的,這裏有一個你的術語。由於被稱爲「閉包」(http://www.jibbering.com/faq/faq_notes/closures.html),這是JavaScript的一個強大而強大的功能,因此您遇到了特定的問題。馬特向你展示的是如何使用匿名函數和一種稱爲「柯里」的技術來解決閉包屬性(有時會像你所看到的那樣)。請參閱http://ejohn.org/blog/partial-functions-in-javascript/和http://stackoverflow.com/questions/1413916/。 – 2009-11-22 21:57:31

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