问题描述
document.addEventListener('DOMContentLoaded',() => {
});
我了解到,对于常规脚本,此事件侦听器确保JS不会引用尚未加载的节点。内容在 DOMContentLoaded触发后执行。
我还read在被DOMContentLoaded
触发之前执行模块(由于其内置的defer
属性)。
我使用的模块似乎不需要DOMContentLoaded
侦听器。我可以确认他们不需要DOMContentLoaded
侦听器来正确访问节点吗?
而且,我想不起来如何测试,所以我在这里问。如果您知道我能做到的,请分享!
解决方法
我认为这篇文章应该为您清除所有内容,它的图片https://flaviocopes.com/javascript-async-defer/#the-position-matters
当defer
存在时,它指定在页面完成解析后执行脚本,因此可以保证脚本可以访问没有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。
脚本属性async
和defer
,don’t block DOMContentLoaded
。 JavaScript模块的行为类似于defer
,它们也不会阻止它。
这可以使用type="module"
<script type="module">
alert("Alert from script")
</script>
<script type="text/javascript">
alert("Page loaded")
</script>
如您所见,无论执行什么顺序,页面都会在执行任何模块之前加载。