模块是否阻止使用 DOMContentLoaded 侦听器的需要?

Do modules prevent the need to use the DOMContentLoaded listener?

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

});

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

我还 read 执行了一个模块 DOMContentLoaded 被触发之前(由于它构建的 defer 属性中).

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

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

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

您可以看到 here 表示行为的模式。

无论如何,脚本总是在 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's compatibility 所有浏览器。

脚本属性 asyncdeferdon’t block DOMContentLoaded。 JavaScript 模块的行为类似于 defer,它们也不会阻止它。

这可以使用 type="module"

进行测试

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

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

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

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

defer存在时,指定脚本在页面解析完成时执行,因此可以保证脚本访问没有DOMContentLoaded[=13=的节点]