使范围函数可以从

时间:2019-01-04 12:06:56

标签: javascript

我的代码的简化示例:

<head>
<script type="text/javascript">
  main();
  
  function main() {
    if(document.readyState == 'complete') {
      function a() { /*do stuff*/ }
      function b() { /*do stuff*/ }
    } else {
      setTimeout(function() { main(); }, 1000);
    }
  }
</script>
</head>
<body onload="javascript: main();">
  <div onclick="javascript: a();"></div>
  <div onclick="javascript: b();"></div>
</body>

我想知道是否有一种方法可以识别a()b()的onclick事件,而无需在文档的末尾放置<script>标签。我知道我可以通过使变量和函数全局化来相对容易地做到这一点,但这不是一个好习惯。我可能可以利用闭包,但是我的原始代码比2具有更多的功能,这会很痛苦。

2 个答案:

答案 0 :(得分:1)

移动脚本元素无济于事。

ab函数存在于main函数的范围内,无法在其外部访问。

onclick函数取决于ab是全局变量。

要么使它们成为全局变量,要么将onclick属性转换为JavaScript addEventListener调用(在main函数内部)。

答案 1 :(得分:1)

  

我知道我可以通过使变量和函数全局化来相对容易地做到这一点,但这不是一个好习惯。

如果要使用onxyz属性类型的事件处理程序,则必须使这些函数可以全局访问。

不使用它们的众多原因之一。

  

...没有将标签放在文档末尾。

这是一个奇怪的要求,因为它是where the script tag should go

但是您可以通过以下两种方式来实现:

  1. 使用DOMContentLoaded事件,并在事件处理程序中使用addEventListener连接处理程序。

  2. 使用setTimeout循环等待元素出现(通常,对于没有DOMContentLoaded的环境,如果有剩余的话,这是一个后盾)。

  3. 使用事件委托,将事件挂接到documentdocument.body上,然后通过查看event.target来检查事件是否通过了您感兴趣的元素其父元素(或使用相对较新的closest方法)。

除非将script保留在head的确有很好的理由,否则您最好的选择是:

<head>
</head>
<body>
  <div id="divA">divA</div>
  <div id="divB">divB</div>
<script type="text/javascript">
  main();
  
  function main() {
    document.getElementById("divA").addEventListener("click", function a() {
       console.log("a click");
    });
    document.getElementById("divB").addEventListener("click", function b() {
       console.log("b click");
    });
  }
</script>
</body>

...使用id的地方只是一个例子。实际上,通常可以通过与document.querySelectordocument.querySelectorAll一起使用的CSS选择器来识别相关元素。


旁注:您不能在javascript:属性型事件处理程序上使用onxyz伪协议。 (您可以在需要URL的地方使用它,例如href或书签。)