Javascript 的适当超时
Proper timeout for Javascript
我知道 CSS 转换不适用于 auto
关键字,所以如果我想应用 transition: left 2s, right 2s;
必须从(比方说)0 到 100.
我有一个脚本可能会向左或向右改变对象的位置,但如果 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 也可能有用:它是一个(非官方的)所有导致页面重排的列表。
我知道 CSS 转换不适用于 auto
关键字,所以如果我想应用 transition: left 2s, right 2s;
必须从(比方说)0 到 100.
我有一个脚本可能会向左或向右改变对象的位置,但如果 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 也可能有用:它是一个(非官方的)所有导致页面重排的列表。