我有一个svg,其上设置了过渡。现在当我向它添加一个具有一些属性变化的类时,只有在DOMContentLoaded事件和addclass事件之间添加延迟时才会发生转换。这是两个例子,第一个没有延迟第二个有无限小延迟:
没有延迟:
! function() {
window.addEventListener('DOMContentLoaded', function() {
var logo2 = document.querySelector("svg");
logo2.classList.add('start');
});
}();
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 104.75 32.46">
<defs>
<style>
polygon {
fill: red;
transition: opacity 3s ease-out, transform 3s ease-out;
opacity: 0;
}
.start polygon {
opacity: 1;
}
#A1 polygon {
transform: translate(100px, 100px);
transition-delay: 1s;
}
/*styles after animation starts*/
.start #A1 polygon {
transform: translate(0px, 0px);
}
</style>
</defs>
<title>Logo</title>
<g id="A1">
<polygon class="right" points="0.33 31.97 0.81 26.09 13.61 3.84 13.13 9.72 0.33 31.97" />
</g>
</svg>
延迟:
! function() {
window.addEventListener('DOMContentLoaded', function() {
var logo2 = document.querySelector("svg");
setTimeout(function(){
logo2.classList.add('start');
},0);
});
}();
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 104.75 32.46">
<defs>
<style>
polygon {
fill: red;
transition: opacity 3s ease-out, transform 3s ease-out;
opacity: 0;
}
.start polygon {
opacity: 1;
}
#A1 polygon {
transform: translate(100px, 100px);
transition-delay: 1s;
}
/*styles after animation starts*/
.start #A1 polygon {
transform: translate(0px, 0px);
}
</style>
</defs>
<title>Logo</title>
<g id="A1">
<polygon class="right" points="0.33 31.97 0.81 26.09 13.61 3.84 13.13 9.72 0.33 31.97" />
</g>
</svg>
正如你在第二个例子中所看到的,我添加了0秒的延迟,但它导致动画工作,为什么?
更新1:嗯......我们都错了: - )
我在没有DOMContentLoaded
的情况下尝试了相同的代码,没有延迟。它仍然没有延迟添加转换:
! function() {
var logo2 = document.querySelector("svg");
logo2.classList.add('start');
}();
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 104.75 32.46">
<defs>
<style>
polygon {
fill: red;
transition: opacity 3s ease-out, transform 3s ease-out;
opacity: 0;
}
.start polygon {
opacity: 1;
}
#A1 polygon {
transform: translate(100px, 100px);
transition-delay: 1s;
}
/*styles after animation starts*/
.start #A1 polygon {
transform: translate(0px, 0px);
}
</style>
</defs>
<title>Logo</title>
<g id="A1">
<polygon class="right" points="0.33 31.97 0.81 26.09 13.61 3.84 13.13 9.72 0.33 31.97" />
</g>
</svg>
我还注意到jQuery不会导致重排。下面是一个内联jquery代码的示例,在加载CSSOM之前仍然不会触发ready
函数。如果我们有外部jquery,那么在CSSOM准备就绪之后就会触发就绪事件,而不是内联jquery。我已经达成的理解是CSSOM在渲染html dom后需要几毫秒。所以直到下载外部jquery CSSOM就准备好了。 DOMContentLoaded
根本不关心是否加载了样式表,也就是说它不关心CSSOM是否准备就绪。
答案 0 :(得分:7)
因为那是DOMContentLoaded的作用:当解析DOM时,但在CSSOM之前(因此在应用样式之前)它会触发。
如果您不想等待load
活动,
一种方法是通过在任何文档的元素(例如offsetXXX
)上调用<body>
属性来强制浏览器在脚本执行(同步)之前进行绘制:< / p>
! function() {
window.addEventListener('DOMContentLoaded', function(){
document.body.offsetTop; // force a CSS repaint
var logo2 = document.querySelector("svg");
logo2.classList.add('start');
});
}();
&#13;
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 104.75 32.46">
<defs>
<style>
polygon {
fill: red;
transition: opacity 3s ease-out, transform 3s ease-out;
opacity: 0;
}
.start polygon {
opacity: 1;
}
#A1 polygon {
transform: translate(100px, 100px);
transition-delay: 1s;
}
/*styles after animation starts*/
.start #A1 polygon {
transform: translate(0px, 0px);
}
</style>
</defs>
<title>Logo</title>
<g id="A1">
<polygon class="right" points="0.33 31.97 0.81 26.09 13.61 3.84 13.13 9.72 0.33 31.97" />
</g>
</svg>
&#13;
答案 1 :(得分:4)
正如您在第二个示例中所看到的,我添加了0秒的延迟,但 导致动画有效,为什么?
由于DOMContentLoaded
事件触发时尚未加载CSS对象模型
初始HTML文档具有时触发DOMContentLoaded事件 已完全加载和解析,无需等待样式表, 图像和子帧完成加载。一个非常不同的事件负载 应该仅用于检测完全加载的页面。这是一个令人难以置信的 使用负载的流行错误DOMContentLoaded会更多 适当的,所以要小心。
https://developer.mozilla.org/en/docs/Web/Events/DOMContentLoaded
因此,添加css类不会运行动画。
setTimeOut
方法是一个javascript事件,一旦被触发(即使有0次),它将被添加到当前浏览器执行队列的末尾(在你的情况下将在加载CSS模型后添加) )。因此,动画将正常启动。
更新
但是加载CSSOM后jquery domready会激活。所有这些也是如此 SO上的帖子在技术上是不正确的?
domready
使用DOMContentLoaded
所以从理论上说,他们的行为方式相同。
在之前执行延迟脚本标记(内联或外部) CSSOM已加载?
defer属性延迟的脚本在DOMContentLoaded
被触发之前执行。所以答案是肯定的。