我用过
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<button type="button" id="button">Click</button>
<pre id="output">Not Loading...</pre>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.17.0/babel.min.js"></script>
<script type="text/babel">
document.addEventListener('DOMContentLoaded', function () {
const button = document.getElementById('button');
const output = document.getElementById('output');
output.textContent = 'Loading...';
addEventListener('click', function () {
output.textContent = 'Done';
});
});
</script>
</body>
</html>
但似乎document.addEventListener('DOMContentLoaded', function () {});
内的代码未加载。
如果我从代码中删除它,它会突然发挥作用。
我做了JS Bin here。
答案 0 :(得分:34)
这很可能是因为DOMContentLoaded
事件此时已被触发。一般的最佳做法是检查document.readyState以确定您是否需要倾听该事件。
if( document.readyState !== 'loading' ) {
console.log( 'document is already ready, just execute code here' );
myInitCode();
} else {
document.addEventListener('DOMContentLoaded', function () {
console.log( 'document was not ready, place code here' );
myInitCode();
});
}
function myInitCode() {}
答案 1 :(得分:12)
在代码挂钩时,事件已经已经触发了。 Babel standalone的工作方式是通过查找并执行页面上的所有DOMContentLoaded
脚本来响应type="text/babel"
。您可以在index.js
file:
// Listen for load event if we're in a browser and then kick off finding and
// running of scripts with "text/babel" type.
const transformScriptTags = () => runScripts(transform);
if (typeof window !== 'undefined' && window && window.addEventListener) {
window.addEventListener('DOMContentLoaded', transformScriptTags, false);
}
只需直接运行代码,无需等待事件,因为您知道Babel standalone将为您等待。
另请注意,如果您将脚本放在正文末尾,就在结束</body>
标记之前,即使您不使用Babel,也无需等待DOMContentLoaded
。脚本上方定义的所有元素都将存在并可供您的脚本使用。
在评论中你问过:
但是我在开发中使用Babel Standalone,但是在我投入生产时我会预先编译它。我应该在投入生产时重新添加它吗?
如上所述,请确保您的script
代码位于body
的末尾,并且无需使用该事件。
如果您无论如何都要使用它,您可以通过检查document.readyState
来检查事件是否已经运行(在点击链接后,向上滚动一下):
function onReady() {
// ...your code here...
}
if (document.readyState !== "loading") {
onReady(); // Or setTimeout(onReady, 0); if you want it consistently async
} else {
document.addEventListener("DOMContentLoaded", onReady);
}
document.readyState
经历了这些阶段(从上面的链接略微向上滚动):
在文档加载时返回
"loading"
,一旦完成解析但仍加载子资源时返回"interactive"
,并在加载后加"complete"
。
答案 2 :(得分:0)
感谢Ruslan&amp;这里是完整的代码片段,使用后可以方便地分离DOMContentLoaded
处理程序。
'use strict';
var dclhandler = false;
if (document.readyState !== 'loading') {
start();
} else {
dclhandler = true;
document.addEventListener('DOMContentLoaded', start);
}
function start() {
if (dclhandler) { document.removeEventListener('DOMContentLoaded', start); }
console.log('Start the site`s JS activities');
}
答案 3 :(得分:0)
另一种选择是使用layout
事件。 readystatechange
的{{1}}属性已更改时,将触发readystatechange
事件。 readyState
属性可以是以下三个值之一:document
,readyState
或'loading'
。使用'interactive'
事件的另一种方法是在'complete'
的{{1}}事件中寻找DOMContentLoaded
等于readyState
,如以下代码段所示
'interactive'
尽管在您的情况下,document
的{{1}}似乎已经达到readystatechange
。在这种情况下,您只需在上面的代码段中将document.onreadystatechange = function () {
if (document.readyState === 'interactive') {
// Execute code here
}
}
交换为document
。从技术上讲,这等于readyState
事件,而不是'complete'
事件。
详细了解MDN, Document.readyState Document: readystatechange event
答案 4 :(得分:0)
我会使用curl
答案 5 :(得分:0)
https://learnwithparam.com/blog/vanilla-js-equivalent-of-jquery-ready/
function ready(callbackFunc) {
if (document.readyState !== 'loading') {
// Document is already ready, call the callback directly
callbackFunc();
} else if (document.addEventListener) {
// All modern browsers to register DOMContentLoaded
document.addEventListener('DOMContentLoaded', callbackFunc);
} else {
// Old IE browsers
document.attachEvent('onreadystatechange', function() {
if (document.readyState === 'complete') {
callbackFunc();
}
});
}
}
ready(function() {
// your code here
});
答案 6 :(得分:0)
我干净的方法...
if (document.readyState !== 'loading') init()
else document.addEventListener('DOMContentLoaded', init);
function init() {
console.log("Do it !");
...
}
答案 7 :(得分:-1)
我的实时服务器遇到了这个问题。 我的实时服务器在 cloudflare 上运行,带有一些缓存和火箭加载 js。我认为这是导致意外行为的原因。 使用 DOMContentLoaded 时,代码在本地服务器上运行良好,但在 live 上运行不正常。
如果你可以使用jQuery,切换到
jQuery(document).ready(function() {
//code...
})
按预期工作。