在网上瞄到篇文章关于 jQuery 中的事件延时执行 ,作者讲的这个菜单问题,之前写一个菜单控件时处理过,有印象。这不是要说的重点,重点是,在jquery代码中,要实现延时执行一段代码,可以有更“jquery style”的写法,比直接用window.setTimeout/window.setInterval这种“江南style”要优雅一点点,即可利用jquery的功能避免延时后执行环境变化带来的问题(需做闭包处理),又可保持jquery链。这种方法就是使用animate()函数及它支持的callback功能。

动画有两个元素,1是要变化的效果,2是变化的时间跨度,如果变化效果取空,那animate就变成一个能延时执行callback的定时器了:

$div.animcate({\’top\’:\’+=0\’},1000,\’linear\’,function(){
    $(this).text(\’It is time to change!\’);//this指针仍是jquery对象所指
});

//试过效果参数用空{}不行,用{\’\’:\’\’}在ie7、8下不行 

此外,jquery有一个.delay( duration [, queueName] ) 函数可直接用于动画过程中的延时环节,不过它没有callback参数,不能直接用来做定时器。但是进一步玩味一下,发现可以和queue()/dequeue()联合起来实现更优雅的写法:

$div.delay(1000).queue(function(){
    $(this).text(\’It is time to change!\’);
});

 

以下是我把刚好在做的一段代码重构了的例子(实现的是一个动画刷新一串数字的效果):

View Code 

//原来的代码,使用raw api — window.setInterval
$(\’div.numbers\’).each(function (index, div) {
    var $div = $(div);
    var val = parseInt($div.data(\’value\’));
    if (!val)
        return;
    var steps = getSteps(val);
    $div.text(steps[0]);
    if (steps.length > 1) {
        var interval =20,
            stepIndex = 1;
        var intervalHandler = window.setInterval(function () {
            $div.text(steps[stepIndex]);
                        
            if (stepIndex++ == steps.length) {
                window.clearInterval(intervalHandler);
                delete intervalHandler;
            }
            else {
                $div.animate({ \’fontSize\’\’72px\’,\’top\’:\’6px\’ }, 30)
                    .animate({\’fontSize\’:\’64px\’,\’top\’:\’10px\’},20);
            }
        }, interval);
    }
})
//
View Code 

//重构后的代码
var animateStep = function ($div) {
    var steps = $div.data(\’steps\’),
        stepIndex = $div.data(\’stepIndex\’);
    $div.text(steps[stepIndex]);
    if (++stepIndex < steps.length) {
        $div.data(\’stepIndex\’, stepIndex)
            .delay(20)
            .animate({ \’fontSize\’: \’72px\’, \’top\’: \’-=4px\’, \’left\’: \’-=4px\’ }, 20)
            .animate({ \’fontSize\’: \’64px\’, \’top\’: \’+=4px\’, \’left\’: \’+=4px\’ }, 10)
            .queue(function () { $div.dequeue();animateStep($div); });
    }
}

$(\’div.numbers\’).each(function (index, div) {
    var $div = $(div);
    var val = parseInt($div.data(\’value\’));
    if (!val)
        return;
    $div.data(\’steps\’, getSteps(val))
        .data(\’stepIndex\’, 0);
    animateStep($div);
})
//

版权声明:本文为think原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/think/archive/2012/10/08/jquery_queue_for_delay_code.html