使用 jQuery 实现每秒执行一次的常用方法
嘿,朋友!今天咱们来聊聊一个在网页开发里特别实用的小技巧——怎么让一段代码每隔一秒自动跑一次。你可能会想,这有什么好说的?但这东西玩好了,能让你的网页活起来;玩不好,可能还会出各种小bug,让人头疼。放心,我会用最通俗的方式把这件事给你讲透。
最直接的入门方式
先来看最简单的写法。在 JavaScript 世界里,setInterval 这个函数就是专门为周期性执行任务而生的。它的用法特别直观:
setInterval(function() {
console.log("我在每秒说一次话");
}, 1000);
这里的 1000 单位是毫秒,1000 毫秒等于 1 秒,所以这段代码的意思就是:每过一秒,就在控制台打印那句话。你可以直接在浏览器的开发者工具里试一下,打开控制台就能看到结果。
如果你把 jQuery 加进来,玩法就更多了。比如你有个盒子元素,想让它每隔一秒自动出现又消失:
setInterval(function() {
$(".box").slideToggle(500);
}, 1000);
这段代码会让所有 class 为 box 的元素,每隔一秒就滑入滑出一次,动画持续 500 毫秒。效果挺有意思的,你可以亲手试试看。
现代写法让代码更简洁
如果你用的是新版浏览器或者打包工具,箭头函数会让代码看起来更清爽:
setInterval(() => {
$(".box").toggleClass("active");
}, 1000);
toggleClass 这个方法会在元素有某个 class 时去掉它,没有时加上它。配合 setInterval 用,就能实现开关效果的切换。这种写法在 jQuery 项目里很常见,代码量少,意思也清楚。
如何停下来?
定时器开始之后,如果你发现不需要它了,可以调用 clearInterval 来停止:
var timer = setInterval(function() {
console.log("我还在跑...");
}, 1000);
// 过一段时间再停止
setTimeout(function() {
clearInterval(timer);
console.log("已经停止了");
}, 5000);
这段代码先启动了一个每秒执行的定时器,然后又用 setTimeout 在 5 秒后把它关掉。你可以想象成:闹钟响了每秒滴答一次,五秒后你把它关掉了。
一个小陷阱:定时器叠加
这里有个地方需要特别注意。如果 setInterval 里的代码执行时间超过了间隔时间,或者操作是异步的(比如动画没结束就又开始下一次),就会出现任务叠加的情况。来看一个例子:
var timer = setInterval(function() {
$(".box").animate({
opacity: 0
}, 1000, function() {
$(this).animate({
opacity: 1
}, 1000);
});
}, 500);
这段代码本意是让元素淡入淡出,间隔是 500 毫秒一次。但因为动画本身就要 2000 毫秒(1000 + 1000),结果定时器已经在等下一轮的时候,上一轮还没完,多个动画就堆在一起了,效果会乱掉。
怎么避免这个问题呢?一个常用的思路是在执行前先停掉之前的定时器:
var timer = null;
function startAnimation() {
clearInterval(timer);
timer = setInterval(function() {
$(".box").animate({
opacity: 0
}, 1000, function() {
$(this).animate({
opacity: 1
}, 1000);
});
}, 2000);
}
startAnimation();
这样每次调用前都会先清理旧定时器,再开新的,就不会有叠加问题。
用 Promise 和 async/await 来实现
如果你不喜欢 setInterval,也可以用递归调用配合 Promise 来实现同样的效果,这种方式在现代项目里越来越流行:
function repeatEverySecond(fn) {
return new Promise(function(resolve) {
function tick() {
fn();
setTimeout(tick, 1000);
}
tick();
});
}
repeatEverySecond(function() {
console.log("我又执行了一次");
});
用 async/await 写的话会更优雅:
async function repeatTask() {
while (true) {
await new Promise(function(resolve) {
setTimeout(resolve, 1000);
});
console.log("每秒执行一次,现在停了也不会影响");
}
}
repeatTask();
这种方式的好处是你可以在任何地方用 await,不用担心 setInterval 的回调嵌套问题。而且想停掉的时候,只要不再调用或者加个条件判断就行。
实际项目中的常见场景
在真实项目里,这种每秒执行一次的写法通常用在哪里呢?
实时数据更新:比如股票价格、天气信息、消息通知,每隔几秒拉一次数据:
setInterval(function() {
$.get("/api/stock-price", function(data) {
$("#price").text(data.price);
});
}, 1000);
心跳检测:检查用户是否还在线:
setInterval(function() {
$.post("/api/heartbeat", {
userId: currentUserId
});
}, 5000);
动画循环:一些背景动画、loading 效果:
setInterval(function() {
$(".spinner").toggleClass("rotating");
}, 1000);
写在最后
setInterval 本身是个很基础的工具,但用好它需要一点经验。记住三个关键点:一是注意清理定时器,别让它一直跑浪费资源;二是注意任务叠加的问题,别让动画或请求堆在一起;三是选择适合你场景的写法,简单的用 setInterval,复杂的用 Promise 递归可能更清晰。
你现在可以打开浏览器控制台,随便找个网页,试着运行一下这些代码,看看实际效果。动手操作比看十遍教程都管用。如果遇到问题,随时可以回来看看这篇笔记。
