Javascript 为什么可以';我们不能使用for循环来创建动画吗?

Javascript 为什么可以';我们不能使用for循环来创建动画吗?,javascript,jquery,Javascript,Jquery,在jQuery库和offset()方法的帮助下,认为通过编写此简单代码,元素将逐渐改变位置似乎是合乎逻辑的 for (i = 0; i < 900; i = i + .5) { $('#moving-element').offset({ top: i }) } (i=0;i

在jQuery库和offset()方法的帮助下,认为通过编写此简单代码,元素将逐渐改变位置似乎是合乎逻辑的

for (i = 0; i < 900; i = i + .5) { 
    $('#moving-element').offset({ top: i })
}
(i=0;i<900;i=i+.5){ $(“#移动元素”).offset({top:i}) } 浏览器将停止一段时间,并最终将元素移动到距离顶部900px的位置,无法观察到过渡。出于好奇,我写了这封信:

for (i = 0; i < 900; i = i + .5) { 
    $('#moving-element').offset({ top: i }); 
    console.log(i)
}
(i=0;i<900;i=i+.5){ $('#moving element').offset({top:i}); 控制台日志(i) } 要查看控制台是否正在输出连续的数字,这很好,但它仅在for循环结束后偏移元素


为什么在执行代码时不逐步执行此操作?

因为javascript是单线程事件建模的运行时(至少在当前版本中是这样)


这意味着在运行
for
循环时,不能运行其他任务。这意味着接受用户输入、更新屏幕等。因此循环将完全运行,然后显示最终结果。

问题在于javascript是单线程的,在处理时会阻塞ui和事件队列。您需要使用
setTimeout
或其他一些异步流控制机制来生成绘图任务,以便在执行动画时浏览器可以执行其他操作

// Our animate function changes the offset, waits a while, then repeats
function animate(n) {
    // Change the offset to the passed in value
    $('#moving-element').offset( {top: n});

    // If the passed in value is equal to 900, stop exection
    if (n === 900)
        return;        

    // Otherwise, set a timer which will trigger our animate function again
    // after 10 milliseconds
    setTimeout(function() {
        // Increment n when passing it into our function
        animate(n++):
    }, 10);
}

// Call the function to begin with
animate(0);

这将让您了解循环的
速度有多快。单击按钮后,for循环将开始执行,只有当它达到第一百万次迭代时,才会在屏幕上显示警报。

你认为for循环需要多长时间?JS不是这样工作的。几乎所有函数都将尽快返回。因此,实际上你是在告诉元素在不到一秒钟的时间内移动900次。这就是为什么您只能看到最后一个动画,并且必须使用回调。因为当DOM被JavaScript更改时,浏览器不会立即更新DOM。如果他们这样做了,你典型的浏览体验会非常慢。我已经量化了循环所需的时间,并用更小的间隔进行了实验,得到了准确的结果。。我只需要了解语言是如何工作的,谢谢JavaScript是单线程的,浏览器不是。理论上,它每次都可以重新绘制窗口,但没有理由这样做,因为这样做的速度会非常慢。@AnthonyGrist我认为tknoe关于“更新屏幕”的意思是使用javascript来操作dom。这似乎与浏览器重新绘制无关。:)@你说得对,浏览器是。但是创建一个永不结束的while循环——您将根本无法使用浏览器。Javascript执行会阻止用户输入。这就是为什么浏览器会说“这个脚本正在使用4eva!你想让我停止它吗?!”这是你在退出浏览器之前唯一能停止它的功能这只是因为你正在插入
setTimeout
。for循环在这里除了创建和插入一组指令以在js事件循环中异步运行之外,什么都不做。然而,这将解决问题。但他的问题并不是因为for循环太快,而是因为javascript是单线程和ui阻塞的。