JavaScript: Trigger CSS Transition with window.setTimeout

拜拜、爱过 提交于 2019-12-02 15:52:33

问题


This is (obviously) part of a bigger project, but I am trying to trigger a CS transition on setTimeout.

(I know about using CSS animations, but this is not just about repeated transitions).

A CSS transition will occur when a property changes. For my own purposes, I use setAttribute as that isolates the behaviour from other class-related stuff, but the behaviour below works the same.

Assuming the HTML and other code is in place, here is simplified version:

var test=document.querySelector('div#test');    
window.setInterval(doit,4000);
function doit() {
    test.removeAttribute('thing');
    test.innerHTML=new Date();
    test.setAttribute('thing',null);
}

The CSS is:

div#test {
    opacity: 0;
}
div#test[thing] {
    transition: opacity 1s;
    opacity: 1;
}

The trick I am trying is to change clear the attribute and then set it again — that should trigger the CSS change. It doesn’t work as above. However, if I delay setting the attribut by 0 seconds, it does work:

function doit() {
    test.removeAttribute('thing');
    window.setTimeout(function() {
        test.setAttribute('thing',null);
    },0);
    test.innerHTML=new Date();
}

The question is: why does it not work unless I add this minuscule delay, and is there a better way to do this?

I would like an answer without jQuery.

Note: I have accepted an answer below. The following code will work:

function doit() {
    test.removeAttribute('thing');
    test.offsetHeight;                  //  force update
    test.innerHTML=new Date();
    test.setAttribute('thing',null);
}

Thanks


回答1:


This is because of how the browser queues reflow and relayout changes. The browser does not do these things sequentially like how you've structured your code. It adds the changes to a queue and attempts to perform multiple operations at once (for performance reasons).

The browser is trying to be "smart" here - it sees that the styles are going to wind up exactly as they were before, so the removal and re-addition of the attribute are batched together in one update and thus you see no change. Adding the setTimeout, even with a 0 second delay, forces the browser to reflow at that point.

Here's a link to another similar question: Force browser to trigger reflow while changing CSS

And here's a comprehensive list of methods/properties you can call in JS to force a reflow in your JS (instead of using setTimeout): https://gist.github.com/paulirish/5d52fb081b3570c81e3a



来源:https://stackoverflow.com/questions/39446904/javascript-trigger-css-transition-with-window-settimeout

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