简体   繁体   English

AddEventListener匿名函数中的Javascript变量作用域

[英]Javascript variable scope in addEventListener anonymous function

When clicking on each div it should alert '1' if div 1 was clicked on or '5' if div 2 was clicked on. 当点击每个div时,如果单击div 1则应该警告'1',如果单击div 2则应该警告'5'。 I have tried to make this code as easy to as possible because this is needed in a much larger application. 我试图尽可能地使这些代码变得容易,因为在更大的应用程序中需要这样做。

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

Thanks for your help! 谢谢你的帮助! :-) :-)

The problem is that the event listeners and 'total' both exist in the same scope (init()) 问题是事件监听器和'total'都存在于同一范围内(init())

The event functions are always going to reference total within the init() scope, even if it is changed after the event functions are declared 事件函数始终在init()范围内引用total,即使在声明事件函数后更改它也是如此

To get around this, the event functions need to have a 'total' in their own scope which will not change. 为了解决这个问题,事件函数需要在自己的范围内具有“总数”,这不会改变。 You can add another layer of scope using an anonymous function 您可以使用匿名函数添加另一个范围层

For example: 例如:

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

The anonymous functions are passed init()'s current 'total' value as a parameter. 匿名函数作为参数传递给init()当前的'total'值。 This sets another 'total' to the anonymous function's scope, so it does not matter if init()'s total changes or not, because the event function will FIRST reference the anonymous function's scope. 这为匿名函数的范围设置了另一个'total',因此init()的总和是否发生变化并不重要,因为事件函数将首先引用匿名函数的作用域。

Edit: 编辑:

Also, you need to place a semicolon after the closing brace of the helper function, otherwise the script will complain that 'event' is undefined. 此外,您需要在辅助函数的右括号后面放置一个分号,否则脚本会抱怨'event'未定义。

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

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

This is almost the same but i think it will be better: 这几乎是一样的,但我认为它会更好:

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

instead of: 代替:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM