如果发生了某些事件,我需要通知用户。为此,我编写了类似生成模式窗口并将其插入页面正文的内容。
该方法showMessage
显示一些消息。
可能会出现这样的情况,即某条消息已经流出(即某事引起showMessage
),用户还没有阅读,但是已经有新消息到达。一般来说,您需要组织一个消息队列。也就是说,如果用户关闭消息,队列不为空,那么一条新消息立即飞出。
编码
window.onload = function() {
setInterval(() => foo(), 3000); // генерация нового сообщения каждые 3 сек
};
cnt = 0;
function foo() {
showMessage('cnt', cnt);
cnt += 1;
}
messageQueue = [];
showMessage.show = false; // флаг того, что сейчас отображается сообщение
function showMessage(caption, message) {
// если показывается сообщение, то поместить новое сообщение в очередь
if (showMessage.show) {
messageQueue.push([caption, message]);
console.log(messageQueue);
return;
}
let html = `
<div class="modal">
<div class="modal-content">
<div class="modal-header">
<button class="close" id="close">×</button>
<h2>${caption}</h2>
</div>
<div class="line"></div>
<div class="modal-body">
<p>${message}</p>
</div>
</div>
</div>
`;
let parser = new DOMParser();
let doc = parser.parseFromString(html, 'text/html');
let div_modal = doc.body.firstChild;
document.body.append(div_modal);
let div_content = document.querySelector("div.modal-content");
let button_close = document.querySelector("button#close");
function window_onclick(event) {
if (event.target === div_modal) {
closeDialog();
}
}
window.addEventListener('click', window_onclick, false);
function button_no_onclick(event) {
closeDialog();
}
button_close.addEventListener("click", button_no_onclick, false);
function closeDialog() {
window.removeEventListener('click', window_onclick);
button_close.removeEventListener('click', button_no_onclick);
div_modal.classList.toggle('show-modal');
div_content.classList.toggle('show-content');
// удаляем через 0.4 сек, чтобы успела отработать анимация
setTimeout(function() {
div_modal.remove();
}, 0.4 * 1000);
showMessage.show = false; // сбрасываем флаг отображения сообщения
// если очередь не пуста, то через 0.4 сек показать новое сообщение
// за 0.4 сек старое сообщение закроется
if (messageQueue.length > 0) {
msg = messageQueue.shift();
setTimeout(() => showMessage(msg[0], msg[1]), 0.4 * 1000);
}
}
// тут нужна минимальная задержка, чтобы браузер нормально нарисовал анимацию
// Задержка 4 мс нужна для корректной работы в Firefox (в Chrome и с 1 мс работает)
setTimeout(function() {
div_modal.classList.toggle('show-modal');
div_content.classList.toggle('show-content');
}, 4);
showMessage.show = true; // установить флаг отображения сообщения
}
/*
Modal dialog
*/
/* The Modal (background) */
.modal {
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.5);
opacity: 0;
-webkit-transition: opacity 0.4s;
-moz-transition: opacity 0.4s;
-o-transition: opacity 0.4s;
transition: opacity 0.4s;
}
.show-modal {
opacity: 1;
}
/* Modal Content */
.modal-content {
position: relative;
background-color: white;
margin: auto;
/*padding: 5px 0 10px 0;*/
border-radius: 6px;
width: 50%;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
color: #333333;
top: -300px;
-webkit-transition: top 0.4s;
-moz-transition: top 0.4s;
-o-transition: top 0.4s;
transition: top 0.4s;
}
.show-content {
top: 0;
}
/* The Close Button */
.close {
color: #cbcbcb;
float: right;
font-size: 28px;
font-weight: bold;
border: 0;
background-color: transparent;
}
.close:hover,
.close:focus {
color: #7f7f7f;
text-decoration: none;
cursor: pointer;
}
.modal-header {
padding: 10px 16px;
}
.modal-body {
padding: 10px 16px;
}
.modal-footer {
padding: 10px 16px;
text-align: right;
}
.modal-footer > button {
width: 62px;
height: 34px;
background-color: inherit;
border: 1px solid #cccccc;
border-radius: 4px;
}
.modal-footer > button:hover {
background-color: #e6e6e6;
cursor: pointer;
}
.line {
width: 100%;
border-bottom: 1px solid #e5e5e5;
position: absolute;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button type="button" onclick="showMessage('Header', 'Body')">Show Message</button>
<button type="button" onclick="alert('Заглушка')">Show Confirm Dialog</button>
</body>
</html>
html 和 css 没有什么有趣的。一切都与 JavaScript 有关:showMessage
.
一般来说,一切运作良好。
但是有一种情况(随机,如果用户快速从队列中关闭消息),当消息关闭时,队列不为空,调用下一条消息,页面背景发生变化,消息本身不出现(旧的飞走了,新的没有)。
看起来像这样
可能是什么问题呢?在哪里挖?
PS:0.4 * 1000
-打开/关闭模态窗口的动画持续时间(以秒为单位)
PPS:window.onload
添加每 3 秒生成一条新消息
在我看来,问题出在一线
showMessage.show = false
。由于您实际上在 0.4 秒后关闭了窗口,并show
“立即”设置了标志。从队列中“立即”接收到一条消息,并在 0.4 秒后才显示,这也有点尴尬。
把所有东西都变成了一个一致的形式——这个错误似乎已经消失了。测试一下。