Javascript 的适当超时

Proper timeout for Javascript

我知道 CSS 转换不适用于 auto 关键字,所以如果我想应用 transition: left 2s, right 2s; 必须从(比方说)0100.

我有一个脚本可能会向左或向右改变对象的位置,但如果 left 设置为 0,我无法设置 right: 100(它必须是 auto).

所以我想出了这个解决方案。

function moveObject(direction) {
    direction ? myobject.style.right = 0 : myobject.style.left = 0;    //same position as auto but can be transitioned
    direction ? myobject.style.right = "50vw" : myobject.style.left = "50vw";    //actual transition
}

function resetObject() {
    myObject.style.left = myObject.style.right = "auto";   //now I can move to either right or left again
    //I don't need an animation on reset
}
#myobject {
    position: absolute;
    left: auto;
    right: auto;
    
    /*width, height...*/
}
<div id="myObject"></div>

这没有用(分配给 0 的内容被完全忽略了)。

所以我想出了这个解决方案(与上面相同,但使用 setTimeout(..., 0);

function moveObject(direction) {
    direction ? myobject.style.right = 0 : myobject.style.left = 0;

    setTimeout(function() {
        direction ? myobject.style.right = "50vw" : myobject.style.left = "50vw";    //this is executed async
    }, 0);
}

function resetObject() {
    myObject.style.left = myObject.style.right = "auto";
}
#myobject {
    position: absolute;
    left: auto;
    right: auto;
    
    /*width, height...*/
}
<div id="myObject"></div>

这改进了结果,但有时(它似乎是完全随机的,但在小屏幕上更频繁),过渡仍然不会发生。

我以为这是因为有时候异步函数执行的太快,所以我尝试将延迟增加到10ms,但有时还是会出现问题(不太频繁)。

现在,我可以进一步增加该值,但是:

那么,是否有一个最小数量可以保证输出成功?

如果不是,怎样才能达到同样的效果?

正如@Akxe 所建议的,解决方案是重排页面。换句话说,浏览器会一起刷新 DOM 的多个更改。这会稍微加快页面速度,但会导致一些问题,例如我描述的问题 (further information here)

按照建议here,解决方案是这样一个函数:

function reflow() {    //this will be called between the two elements
    void(document.documentElement.offsetWidth);
}

function moveObject(direction) {
    direction ? myobject.style.right = 0 : myobject.style.left = 0;
    reflow();   //the line above is now flushed
    direction ? myobject.style.right = "50vw" : myobject.style.left = "50vw";
}

function resetObject() {
    myObject.style.left = myObject.style.right = "auto";
}
#myobject {
    position: absolute;
    left: auto;
    right: auto;
    
    /*width, height...*/
}
<div id="myObject"></div>

这个功能实际上对我有用,即使没有使用 void, but I preferred keeping it since in the referenced question 有人指出它对他不起作用,而且为了更清楚。

This 也可能有用:它是一个(非官方的)所有导致页面重排的列表。