js 有没有队列执行这种东西?
我有个js写的函数如下:
function myAlert(str, config) {
if ($('#alertBox').length) {
$('#alertBox').remove();
}
var defaultConfig = {
millisecond: 3000
};
config = Object.assign(defaultConfig, config);
str = '<div id="alertBox">' + str + '</div>';
$('body').append(str);
$('#alertBox').css({
'top': parseFloat((($(window).height()) / 2 + window.scrollY) * 9 / 10) + 'px',
'left': Math.floor(($(window).width() - $('#alertBox').outerWidth(true)) / 2) + 'px',
'zIndex': typeof config.zIndex == 'undefined' ? '' : config.zIndex
}).fadeIn('fast').delay(parseInt(config.millisecond)).fadeOut('fast', function () {
this.remove();
});
}
这个函数是用来做提醒的,调用一次页面弹出一个提醒框,显示 3 秒然后自动关掉,现在有个问题,如果我有两次调用,并且调用间隔很小的话,那么第一次的弹框内容还没有显示够 3 秒的时间就直接显示了第二次的弹窗内容给取代了,我尝试了很久不知道怎么解决这个问题,希望有个前端大佬帮忙看看,谢谢。
我的期望是即使我调用 n 次,他每次都要显示我定义的那个 millisecond 时间之后关闭,间隔 300 毫秒后,再继续显示下一个,直到 n 次显示完再关闭。
经大佬指点,我自己总结成了一个方法写到了下面,基本达到目的了,再次谢谢各位回答的大佬!
function oppoMsg(str, config) {
if ($('#alertBox').length) {
$('#alertBox').remove();
}
str = '<div id="alertBox">' + str + '</div>';
$('body').append(str);
$('#alertBox').css({
'top': parseFloat((($(window).height()) / 2 + window.scrollY) * 9 / 10) + 'px',
'left': Math.floor(($(window).width() - $('#alertBox').outerWidth(true)) / 2) + 'px',
'zIndex': typeof config.zIndex == 'undefined' ? '' : config.zIndex
}).fadeIn('fast').delay(parseInt(config.millisecond)).fadeOut('fast', function () {
this.remove();
});
}
function queueFn(fn) {
const queue = [];
let running = false;
function next() {
if (running) return;
if (!queue.length) return;
running = true;
var args = queue.pop(), config = {millisecond: 3000};//这里做了一些改动
config = Object.assign(config, args[0][1]);
try {
fn.call(this, args[0][0], config);
} catch (err) {
console.error(err)
}
setTimeout(function () {
running = false;
setTimeout(function () {
next();
}, 200);//这里又加了一个定时器,先消失再弹出来
}, config.millisecond);
}
return function (...args) {
queue.push([args, this]);
next();
}
}
const queuedOppoMsg = queueFn(oppoMsg);
function myAlert(str, type, config, idName, reportError) {
type = type || 'alert';
idName = idName || 'showApiAlert';
reportError = reportError || false;
if (reportError) {
}
switch (type) {
case 'alert':
alert(str);
break;
case 'msg':
//TO DO 要解决这个提醒会被覆盖的问题
queuedOppoMsg(str, config);
break;
case 'notice':
break;
}
测试代码:
for (var i = 0; i < 2; i++) {
myAlert('test' + i, 'msg');
}
回复
1个回答
test
2024-06-25
function queueFn(fn){
const queue = [];
let running = false;
function next(){
if(running) return;
if(!queue.length) return;
running = true;
const [[str, {zIndex = "", millisecond = 3000}], context] = queue.pop();
try{
fn.call(this, str, {zIndex, millisecond});
} catch(err){console.error(err)}
setTimeout(function(){
running = false;
next();
}, millisecond);
}
return function(...args){
queue.push([args, this]);
next();
}
}
const queuedMyAlert = queueFn(myAlert);
原来调用 myAlert 的地方,改为调用 queuedAlert 即可。
回复
适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容