当我单击窗口时,CSS转换不会触发。
const div = document.querySelector('div');
window.onclick = function() {
div.classList.add('fade');
div.classList.add('in');
}
.fade {
opacity: 0;
}
.fade.in {
transition: opacity 2s linear;
opacity: 1;
}
<div>aaaa</div>
然后我修改脚本,使用setTimeout
添加第二类in
,它可以工作。
const div = document.querySelector('div');
window.onclick = function() {
div.classList.add('fade');
setTimeout(function() {
div.classList.add('in');
});
}
.fade {
opacity: 0;
}
.fade.in {
transition: opacity 2s linear;
opacity: 1;
}
<div>aaaa</div>
所以我想,是不是需要一段时间之间的CSS属性变化才能触发CSS转换呢?
因此,我添加了添加类之间的时间。这也没用。
<script>
window.onclick = function(){
div.classList.add('fade');
for(var i=0;i<10000; i++){
console.log(i);
}
div.classList.add('in');
}
</script>
为什么同一个函数中的更改类不能触发css转换?
发布于 2017-07-24 01:25:25
如果我们深入研究JavaScript V8引擎的工作,就可以分解执行,从而澄清当前的行为。JavaScript是单线程的,更准确地说是
一个线程==一次调用堆栈==一件事
如上面所示,setTimeout是WebAPI的一部分,它位于浏览器中。WebAPI的优先级低于作为核心JavaScript函数的“堆栈”方法。
,如上面提到的,“这是关键的部分:对元素的classList进行多个更改不会导致每个更改都重新绘制元素”
造成这种情况的原因是“呈现队列”,它是V8体系结构的功能部分,如下所示:
呈现发生在“堆栈”方法执行之间。在所有堆栈都为空之后,将触发'event循环‘,并提取传递给WebAPI的任何方法。这就是原因,在第二个场景中,当脚本被更改为使用setTimeout时,它可以工作。
更详细的解释可以在菲利普罗伯茨博客上看到。
发布于 2017-07-24 00:51:42
在第一个示例中,在重新绘制元素之前,要同时将两个类添加到元素中。不透明度的初始值为1,.fade.in
的不透明度也为1,因此元素的不透明度没有变化。
这是关键的部分:对元素的classList 进行多个更改不会导致使用每个重新绘制元素。
延迟添加"in“类意味着浏览器首先必须将元素呈现为简单的.fade
,其不透明度为0。超时后,浏览器意识到需要将元素的不透明度从0转换为1,因此它执行必要的插值。
https://stackoverflow.com/questions/45275438
复制