سؤال

I have already tried my luck and searched a lot but could not find a solution to my issue. The function in question is supposed to draw a set of lines using jcanvas and pause the drawing according to prerecorded times. Instead it just draws the entire lines at once. Here is the jQuery code in question:

$("#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]);                               
        }
});
هل كانت مفيدة؟

المحلول

Because the loop finishes before your setTimeout() callback is run, your callback will always reference the final state of the object (that is, its state after the entire loop has run).

To fix this, you can wrap your setTimeout() callback in a closure. By wrapping the callback in a closure function, I am capturing the state of the obj variable. However, in this case, because objects are passes by reference in JavaScript, I have cloned the object (using $.extend) to ensure that its current state (properties and all) is preserved.

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

FWIW, there is an extensive examination of this issue on StackOverflow.

نصائح أخرى

just a simplification of Caleb531's point

$("#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]);      
      })();                         
    }
});
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top