Eri*_*AND 5 html javascript css
考虑以下 HTML 文档:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
body {
background: crimson;
}
div {
transition: opacity 5s;
font-size: 4em;
opacity: 0;
}
.loaded div {
opacity: 1;
}
</style>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('body').className += "loaded";
})
</script>
</head>
<body id="body">
<div>
TEST
</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
div 的不透明度应该设置为 0,并且不透明度的过渡时间为 5 秒。
当 DOM 加载时,主体会被赋予一个将 div 不透明度设置为 1 的类。
我预计 div 不透明度会在 5 秒内从 0 转变为 1。但由于某种原因,它立即发生。
如果我使用 setTimemout,每个都会按预期工作:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
body {
background: crimson;
}
div {
transition: opacity 5s;
font-size: 4em;
opacity: 0;
}
.loaded div {
opacity: 1;
}
</style>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function() {
document.getElementById('body').className += "loaded";
}, 0);
})
</script>
</head>
<body id="body">
<div>
TEST
</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
让我想知道样式是在触发 DOMContentLoaded 事件后加载的。这是正常行为还是我在这里做错了什么?
简洁版本:
您正在进入未明确行为的领域。我建议您使用该load
事件来触发转换。
长版:
当元素的 CSS 属性的计算值更改 ( spec ) 时,会触发 CSS 转换,因此在样式系统首先计算文档的样式之前无法触发 CSS 转换。
样式系统应该在加载相关样式表后对文档执行初始样式传递(即第一次计算计算值)——否则它将必须在样式表完成加载后重新执行工作。
另一方面,它的想法DOMContentLoaded
是在解析 HTML 源代码后立即触发——无需等待任何其他资源(包括样式表)完成加载,因此它自然可以在计算任何样式之前触发。
浏览器具有复杂的启发式方法,可以阻止内联脚本的执行(从而阻止解析和 DOMContentLoaded)并确定初始布局和绘制何时发生。脚本可以强制 reflow/restyle,因此根据特定的网页代码和时间,样式信息可能在脚本运行时可用。我不确定它是否在所有浏览器中都能可靠地工作,但强制布局DOMContentLoaded
可能会导致您的转换正常工作:
div.offsetTop // force layout
Run Code Online (Sandbox Code Playgroud)
当初始 HTML 文档完全加载和解析后,将触发DOMContentLoaded事件,无需等待样式表、图像和子框架完成加载。
该文档建议您应该使用 load 事件:
一个非常不同的事件加载应该仅用于检测完全加载的页面。
所以你会这样做:
window.addEventListener('load', function() {
document.getElementById('body').className += "loaded";
});
Run Code Online (Sandbox Code Playgroud)
请注意,我不仅更改了事件名称,还更改了分配侦听器的对象。