在DOMContentLoaded触发后应用样式? [英] Are styles applied after DOMContentLoaded is triggered?

查看:115
本文介绍了在DOMContentLoaded触发后应用样式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下HTML文件:

 <!DOCTYPE html> 
< html lang =en>
< head>
< meta charset =UTF-8>
< title>标题< / title>
< style type =text / css>
body {
background:crimson;
}

div {
transition:opacity 5s;
font-size:4em;
opacity:0;
}

。加了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>

div的不透明度设置为0,不透明度为5s。



当DOM被加载时,body被赋予一个将div不透明度设置为1的类。



我是期待div不透明度在5秒内从0过渡到1。但是出于某种原因,它会立即发生。



如果我使用setTimemout,则每个按预期工作:

 <!DOCTYPE html> 
< html lang =en>
< head>
< meta charset =UTF-8>
< title>标题< / title>
< style type =text / css>
body {
background:crimson;
}

div {
transition:opacity 5s;
font-size:4em;
opacity:0;
}

。加了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>

让我感到惊讶的是,在DOMContentLoaded事件触发后,样式被加载。这是一个正常的行为,或者我在这里做错了什么?



您正在进入欠规范的行为领域。我建议您使用 load 事件触发转换。



长版本

元素CSS属性的计算值发生变化时触发CSS转换( spec ),所以不能被触发样式系统首先计算文档的样式。



样式系统应该对文档执行初始的样式传递(即计算第一次计算的值)加载相关的样式表之后 - 否则在样式表完成加载后它将不得不重新进行工作。



另一方面, DOMContentLoaded 等待任何其他资源(包括样式表)完成加载,所以它自然可以开火在任何样式计算之前



浏览器有复杂的启发式方法,它会阻止内联脚本的执行(从而解析和DOMContentLoaded)并确定初始布局和绘画何时发生。这些脚本可以强制重排/ restyle ,因此根据具体的网页代码和时间安排,样式信息可以在您的脚本运行时可用。我不确定它是否可以在所有浏览器中可靠地工作,但是从> DOMContentLoaded 强制布局可能会导致您的转换工作:

  div.offsetTop //强制布局


Consider the following HTML document:

<!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>

The div is supposed to have its opacity set to 0 and a 5s transition on opacity.

When the DOM is loaded, the body is given a class that set the div opacity to 1.

I'm expecting the div opacity to transition from 0 to 1 in 5s. But for some reason, it happens immediately.

If I use setTimemout, every works as expected:

<!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>

Makes me wonder is styles are loaded after DOMContentLoaded event is triggered. Is this a normal behavior or am I doing something wrong here ?

解决方案

Short version:

You're getting into the area of underspecified behavior. I suggest you use the load event for triggering the transition.

Long version:

A CSS transition is triggered when computed values of an element's CSS properties change (spec), so it can not be triggered before the style system first computes the styles for the document.

The style system ought to do the initial styling pass on the document (i.e. calculate the computed values the first time) after it loads the relevant stylesheets -- otherwise it will have to re-do the work after the stylesheets finish loading.

On the other hand, the idea of DOMContentLoaded is to fire as soon as the HTML source is parsed -- without waiting for any other resources (including stylesheets) to finish loading, so it naturally can fire before any style was calculated.

The browsers have complicated heuristics that block execution of inline scripts (and thus parsing and DOMContentLoaded) and determine when the initial layout and painting happens. The scripts can force reflow/restyle, so depending on the specific web page code and timing, the styling information may be available by the time your script runs. I'm not sure if it works reliably in all browsers, but forcing layout from DOMContentLoaded might cause your transition to work:

div.offsetTop // force layout

这篇关于在DOMContentLoaded触发后应用样式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆