在同一个jquery函数中的前一行之前执行一行

时间:2014-05-22 00:41:18

标签: javascript jquery

这只是一个可以帮助我解决一些基本问题的问题。

我有一个简单的html页面,我放了2个div:#test和#testresult

这个在单独的.js文件中写入的JQUERY很好地包含在html页面中

$(document).ready(function () {
    var cssleft = $("#test");


    (function hhh() {

        cssleft.animate({
            left: "100px"
        }, 3000, function () {
            $('#testresult').html(cssleft.css("left"));
        }).animate({
            left: "-100px"
        }, 3000);

        cssleft.animate({
            width: "100px"
        }, 3000).animate({
            left: "10px"
        }, 3000);

        $('#testresult').html(cssleft.css("left"));

    })();
});

我不明白的是执行的流程。

我期待这段代码逐行:

1 /为#test div设置动画,然后写下' left' #testresult div中的值(100px)。 2 /再次为#test div制作动画。 3 /写下左边的新值' (10px)在#testresult div。

但是,只有在#testresult div被修改为$('#testresult').html(cssleft.css("left"));之后,1 /和2 /才会按预期运行,就像在前两行将0px放入#testresult div之前触发该行一样。

对此有解释吗?

2 个答案:

答案 0 :(得分:2)

简而言之,animate是一个异步函数。该行被执行,但代码不会在执行下一行之前等待它完成。

为了在动画完成时执行某些操作,您应该使用动画完整功能回调,如文档中所示:http://api.jquery.com/animate/

您在第一个动画中的代码中执行的操作。但是,第二个动画不使用完整的函数来运行该行:$('#testresult').html(cssleft.css("left"));因此它将立即执行。

答案 1 :(得分:1)

从技术上讲,Javascript是单线程的。但实际上它确实具有并发性。或者,从我们的人类角度来看,有些东西似乎“同时运行”。例如,两个单独的单独的setIntervals(一种在一定时间后以间隔运行代码的方式)“同时动画”两个单独的对象“。当它正在运行时,我们可以有一个按钮,当点击它时,输出文本。

Example

This是一个很好的解释,真正发生了什么,javascript运行时明智。从文章中可以看出:

while(queue.waitForMessage()){
  queue.processNextMessage();
}

因此,假设初始代码块将是第一条消息。它会设置onLoad,也许会设置一些setIntervals。这将创建新消息。当页面最终加载时,它将被传递到要运行的队列。当超时超时时,它也将被发送到队列中运行。 但是必须在下一条消息运行之前完成消息。所以看起来好像事情正在同时发生,但实际上它只是在队列中运行的短消息。

所以经典的例子是Example

setTimeout(function(){
   result.innerHTML+="1,";
},0); //wait time in ms

result.innerHTML+="2,";

setTimeout(function(){
   result.innerHTML+="3,";
},0); //wait time in ms

result.innerHTML+="4,";

将输出2,4,1,3,。所以会发生这样的事情,即初始消息将运行,创建两个超时,当设置的时间过去时,它会将函数作为消息传递给队列(在本例中为0,这意味着它会立即发送到队列。

应该注意的是,消息应该很短。也许它必须。但这并不能阻止你编写一个非常大的for循环来遍历和处理巨大的2D阵列阻止你的代码(冻结所有东西),这会在几秒钟之后导致“此页面没有响应”警报。或者实际上,根据mozilla文章,alert()实际上阻止了。所以我将修改示例并添加以查看它们停止执行。

另外。特定于您的代码,jQuery增加了混乱,因为jQuery自动将动画排队。比较this jquery code

$("#test").animate({"left":100},2000)
$("#test").animate({"top":100},2000)

使用此plain javscript code;

var x=10;
setInterval(function(){
   x+=1
   test.style.left=x+"px";
},20)

var y=10;
setInterval(function(){
   y+=1;
   test.style.top=y+"px"
},20)

当然,它不是完全相同的代码片段,这将涉及回调。但我认为这说明了我的观点,.animate有一些神奇的排队。

实际上,要结束,看看promises pattern前进是件好事。这使得链接这些异步事件不是一个疯狂的回调集群。