0

我已经尝试过运气并进行了很多搜索,但找不到解决问题的方法。有问题的函数应该使用 jcanvas 绘制一组线条并根据预先记录的时间暂停绘图。相反,它只是一次绘制整条线。这是有问题的jQuery代码:

$("#start").click(function(){
        $("canvas").css("display","block"); 
        var obj = {  strokeStyle: "#000",  strokeWidth: 6,  rounded: true};
        for (i=0;i<counter;i++)
        {
            obj['x'+(i+1)] = arrX[i]; 
            obj['y'+(i+1)] = arrY[i] - 12; 
            setTimeout(function() {
                var interval = setInterval(function() {
                    $("canvas").drawLine(obj);
                }, 0);

            }, timeDiffs[i]);                               
        }
});
4

2 回答 2

0

因为循环在您的setTimeout()回调运行之前完成,所以您的回调将始终引用对象的最终状态(即整个循环运行后的状态)。

要解决此问题,您可以将setTimeout()回调包装在闭包中。通过将回调包装在闭包函数中,我正在捕获obj变量的状态。但是,在这种情况下,因为对象在 JavaScript 中是通过引用传递的,所以我克隆了对象(使用$.extend)以确保保留其当前状态(属性和所有)。

setTimeout((function(obj) {
    return function() {
        var interval = setInterval(function() {
            $("canvas").drawLine(obj);
        }, 0);
    };
}($.extend({}, obj))), timeDiffs[i]);

FWIW,在 StackOverflow 上对此问题进行了广泛的检查

于 2013-12-16T21:31:30.377 回答
0

只是对 Caleb531 观点的简化

$("#start").click(function(){

    $("canvas").css("display","block"); 
    var obj = {  strokeStyle: "#000",  strokeWidth: 6,  rounded: true};
    for (i=0;i<counter;i++)
    {
      (function(){
        obj['x'+(i+1)] = arrX[i]; 
        obj['y'+(i+1)] = arrY[i] - 12; 

        var incremental = $.extend({}, obj);

        setTimeout(function() {
            var interval = setInterval(function() {
                $("canvas").drawLine(incremental);
            }, 0);

        }, timeDiffs[i]);      
      })();                         
    }
});
于 2013-12-16T22:11:54.707 回答