10
document.addEventListener('DOMContentLoaded', () => { 

});

我读到这个事件监听器确保,对于常规脚本,JS 不会引用尚未加载的节点。内容在DOMContentLoaded 被触发后执行)。

我还读过一个模块在触发之前 DOMContentLoaded执行(由于defer它内置的属性)。

我使用的模块似乎不需要DOMContentLoaded监听器。我可以确认DOMContentLoaded他们不需要侦听器来正确访问节点吗?

另外,我想不出如何测试这个,所以我在这里问。如果你知道我怎么做,请分享!

4

2 回答 2

4

我认为这篇文章应该为你清楚,它有很棒的图片https://flaviocopes.com/javascript-async-defer/#the-position-matters

存在时defer,它指定脚本在页面完成解析后执行,因此您可以保证脚本无需访问节点即可DOMContentLoaded

于 2020-08-18T07:22:57.020 回答
3

使用defer时,脚本确实会在页面完全下载后按照它们出现的顺序执行。

您可以在此处看到表示该行为的模式。

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

无论如何,脚本总是在之前执行DOMContentLoaded,您可以在这里测试该理论:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>

<script type="text/javascript">
  document.addEventListener('DOMContentLoaded', () => {
    alert("Alert from script")
  });
  $(document).ready(function() {
    alert("Alert from jQuery")
  });
</script>

<!-- Alerts "Alert from defer -->
<script defer="defer" type="text/javascript" src="https://pastebin.com/raw.php?i=5tF5s4mB"></script>

除非您从就绪状态中删除警报,否则所有脚本都将在它们之前执行,否则它们将按照它们在DOM.

所以你可以确定里面的所有代码DOMContentLoaded都可以访问满载的DOM.

最后,请注意所有浏览器defer的兼容性。

脚本属性asyncdefer不要阻塞DOMContentLoaded。JavaScript 模块的行为类似于defer,它们也不会阻止它。

这可以使用测试type="module"

<script type="module">
  alert("Alert from script")
</script>

<script type="text/javascript">
  alert("Page loaded")
</script>

如您所见,页面在执行任何模块之前加载,无论顺序如何。

于 2020-08-17T07:12:31.763 回答