gpt4 book ai didi

JavaScript 函数和 UI 更新

转载 作者:行者123 更新时间:2023-12-01 10:45:04 24 4
gpt4 key购买 nike

我有一个下面的函数,它将一个相对定位的元素从它现在所在的位置滑动 1000 像素。

for (var i = 0; i < 1000; i++) {
$('.my-element').css(
'left',
parseInt($('.my-element').css('left'), 10) + 1
);
}

这不会产生滑动效果。相反,在执行结束时,元素突然向右移动 1000 像素。

现在,如果我将 UI 更新包装在 setTimeout 中,如下所示:

for (var i = 0; i < 1000; i++) {
setTimeout(function () {
$('.my-element').css(
'left',
parseInt($('.my-element').css('left'), 10) + 1
);
}, 0);
}

这会产生元素向右滑动 1000px 的视觉效果。

现在,根据我的理解和这个 SO 线程,Why is setTimeout(fn, 0) sometimes useful? , UI 更新在浏览器事件队列中排队,就像异步回调像 setTimeout 回调一样排队。

因此,以防万一,基本上,在执行 for 循环时会创建一个包含 1000 个 UI 更新的队列。

在第二种情况下,首先创建一个包含 1000 个 setTimeout 回调的队列,在执行时创建另一个包含 1000 个 UI 更新的队列。

因此,最终,这两种情况都会创建包含 1000 个 UI 更新的相同队列。那么为什么视觉结果会有所不同呢?

我必须在这里查看一些重要的 JavaScipt 和浏览器渲染概念。任何能启发我的人将不胜感激。

注意:以上示例纯粹是为了理解目的,而不是试图创建一个 JS 函数来滑动 DOM 元素。

最佳答案

这可能是最好的思考方式。浏览器可以做两件事之一。它要么运行您的 javascript,要么呈现 webapge,不能两者兼顾。

这是因为 javascript 代码是 100% 阻塞的,这意味着它永远不会放弃控制权,直到浏览器执行完所有阻塞代码。

您的第一个示例仅包含阻塞代码,因此在元素已经位于需要的位置之前,浏览器永远不会有机会呈现。

您的第二个示例包含使用 setTimeout(延迟阻塞代码)的阻塞代码,该代码将一堆阻塞代码排队等待稍后执行(在所有其他阻塞代码完成后),由浏览器自行决定(在其渲染和 javascript 运行周期之间) .

因此第二个示例循环将完全执行,将 1000 个函数排队等待在某个时间点执行,但尽可能接近 0 毫秒。现在阻塞代码已经完成了一个或多个 setTimeout 可能会执行或者浏览器可能会呈现,但实际上发生的事情是相当随机的。但它会在渲染和执行 javascript 之间来回穿梭。

以这段代码为例

setTimeout(function () { //this makes it so the page loads and sits for a second
var delay = 100, //delay between animations
distance = 25, //total distance moved
sync = false; //should this use blocking code

if (sync) {
var i = 0,
elapsed = 0,
last = new Date();
while (i < distance) {
var now = new Date();
elapsed += (now - last);
last = now;
if (elapsed >= delay) {
move(i++);
elapsed -= delay;
}
}
} else {
for (var i = 0; i < distance; i++) {
assyncMove(i, delay * i);
}
}

function assyncMove(position, delay) {
setTimeout(function () {
move(position);
}, delay);
}

function move(position) {
$("div").css("left", position);
}
}, 1000);

您可以更改delaydistancesync 变量。两个循环都等待在每个动画之间移动元素 delay 毫秒。它们都将移动一个 div 总共 distance 像素。然而,一个 (setTimeout) 将有一个可见的动画,而另一个将只是射击。如果同步方法的延迟或距离太长,您实际上会卡住浏览器,异步解决方案不会有这个问题!

http://jsfiddle.net/j79s4o4w/3/

关于JavaScript 函数和 UI 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27323772/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com