css transition is not trigger by add classes in a same function

陌路散爱 提交于 2019-12-10 17:36:01

问题


when I click the window, CSS transition is not trigger.

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>

then I change the script, use setTimeout to add the second class in, it works.

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>

so I think, is nees a period time between CSS property change can trigger CSS transition?

so i add the time between add classes. it also not work.

<script>
window.onclick = function(){
    div.classList.add('fade');
    for(var i=0;i<10000; i++){
        console.log(i);
    }
    div.classList.add('in'); 

}
</script>

why change classes in a same function can not trigger a css transition?


回答1:


If we go deeper in working of JavaScript V8 engine, the execution could be broken down which could clarify the current behavior. JavaScript is single threaded, more precisely

one thread == one call stack == one thing at a time

As shown above setTimeout is part of WebAPIs which comes within browser. The priority of WebAPIs is lower than 'stack' methods which are core JavaScript functions.

As mentioned above "This is the crucial part: making multiple changes to an element's classList does not cause the element to be redrawn with each change"

The reason for this is "Render Queue" which is functional part of V8 architecture as shown below:

The rendering happens between the 'stack' method execution. After all the stack is empty 'event loop' is triggered and it pulls any method which was passed to WebAPIs. This is the reason, in second scenario when the script is changed to use setTimeout, it works.

More detailed explanation of this can be seen on Philip Roberts blog

https://youtu.be/8aGhZQkoFbQ




回答2:


The transition must be defined for the div with the initial state of the opacity (in this case zero).

const div = document.querySelector('div');
window.onclick = function() {
  div.classList.add('fade');
  div.classList.add('in');
}
div {
  opacity: 0;
  transition: opacity 2s linear;
}

.fade {}

.fade.in {
  opacity: 1;
}
<div>aaaa</div>



回答3:


In your first example, you're adding both classes to the element simultaneously before the element gets redrawn. The initial value of opacity is 1, and the opacity of .fade.in is also 1, so there is no change in the element's opacity.

This is the crucial part: making multiple changes to an element's classList does not cause the element to be redrawn with each change.

Delaying the addition of the "in" class means the browser first has to render the element as simply .fade, with an opacity of 0. After the timeout, the browser realizes it needs to transition the element's opacity from 0 to 1, so it performs the necessary interpolation.



来源:https://stackoverflow.com/questions/45275438/css-transition-is-not-trigger-by-add-classes-in-a-same-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!