jquery代码链实现延时执行代码的较优雅办法
在网上瞄到篇文章关于 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对象所指
});
$(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!');
});
$(this).text('It is time to change!');
});
以下是我把刚好在做的一段代码重构了的例子(实现的是一个动画刷新一串数字的效果):

//原来的代码,使用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);
}
})
//
$('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);
}
})
//

//重构后的代码
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);
})
//
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);
})
//
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix