2009-11-22 357 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));