通知提示排队显示时如何保证队列顺序不混乱?
最近在做消息提示功能,需要实现多个通知排队显示的效果。现在的问题是当快速连续触发多个通知时,虽然队列能正确存入,但前一个通知还没完全消失,下一个就提前显示了,导致视觉上重叠。
我尝试用setTimeout控制显示间隔,但发现如果前一个通知的消失动画还没执行完,下一个就会被触发。代码逻辑是这样的:
let queue = [];
function showNotification(msg) {
queue.push(msg);
if (queue.length === 1) {
displayNext();
}
}
function displayNext() {
if (queue.length > 0) {
const msg = queue.shift();
notificationEl.textContent = msg;
notificationEl.style.display = 'block';
setTimeout(() => {
notificationEl.style.display = 'none';
displayNext();
}, 3000); // 3秒后隐藏
}
}
但实际测试时发现,当快速点击多次按钮时,后面的通知会直接覆盖前面的内容,好像setTimeout没有起到排队作用。有没有更好的方式让通知严格按顺序显示并保持间隔?
displayNext,但连续快速触发时,队列已经大于1了,后续的触发被忽略了**。举个例子:
- 第1个通知进来,队列长度是1,触发
displayNext- 显示第1个通知,启动3秒的
setTimeout- 在这3秒内你又点了几次按钮,队列已经变成 [msg2, msg3, ...]
- 但因为队列长度不为1,
displayNext没有再被调用- 第一个通知消失后调用
displayNext,只显示 msg2- msg3 及之后的还在队列里,但没人触发下一次显示
**所以问题的本质是:只有第一次显示时会触发流程,后续的队列项没人继续推进**
---
### ✅ 正确做法是:
**不管队列长度是多少,只要新加了通知,就尝试触发队列流程**,但要判断是否已经在处理中,避免重复触发。
你可以改成这样:
---
### 🧪 补充说明
- 加了个
isProcessing标志位,表示当前是否正在处理通知队列- 每次调用
showNotification都会检查是否需要触发displayNext-
displayNext会持续处理队列,直到清空- 这样就能保证**通知一定按顺序排队显示,不会重叠**
我以前也踩过这个坑,关键是控制流程状态,不是单纯靠 setTimeout 延迟。调试看看队列和标志位变化就明白了。
setTimeout,但它没法精确控制动画完成的时机。建议用 CSS 动画结合transitionend事件来确保前一个通知完全消失后再显示下一个。直接这样:
记得给
notificationEl加上 CSS 动画,比如transition: opacity 0.5s;。这样就能保证顺序不乱了。