RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1092816
Accepted
ioprst
ioprst
Asked:2020-03-10 14:29:25 +0000 UTC2020-03-10 14:29:25 +0000 UTC 2020-03-10 14:29:25 +0000 UTC

弹出队列。消息显示不正确

  • 772

如果发生了某些事件,我需要通知用户。为此,我编写了类似生成模式窗口并将其插入页面正文的内容。

该方法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">&times;</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 秒生成一条新消息

javascript
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Stepan Kasyanenko
    2020-03-10T18:18:27Z2020-03-10T18:18:27Z

    在我看来,问题出在一线showMessage.show = false。由于您实际上在 0.4 秒后关闭了窗口,并show“立即”设置了标志。

    从队列中“立即”接收到一条消息,并在 0.4 秒后才显示,这也有点尴尬。

    把所有东西都变成了一个一致的形式——这个错误似乎已经消失了。测试一下。

    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">&times;</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();
          showMessage.show = false; // сбрасываем флаг отображения сообщения
        }, 0.4 * 1000);
    
        // если очередь не пуста, то через 0.4 сек показать новое сообщение 
        // за 0.4 сек старое сообщение закроется     
        if (messageQueue.length > 0) {
          setTimeout(() => {
            msg = messageQueue.shift();
            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>

    • 1

相关问题

  • 是否可以在 for 循环中插入提示?

  • 如何将 JSON 请求中的信息输出到数据表 Vuetify vue.js?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5