11

问题

我编写了一个脚本来通知用户页面加载缓慢(例如,这是因为互联网连接速度慢)。脚本放在最前面,<head></head>非常简单:

var GLOBAL_TIMEOUT = setInterval(function () {      
    alert("The Internet connection is slow. Please continue waiting.");
}, 30000);

//clear that interval somewhere else when document is ready
$(function () {
    clearInterval(GLOBAL_TIMEOUT);
});

问题

在当前示例中,信息只是被警告。是否有任何其他可能的方式来通知用户页面加载缓慢(特别是当头部中的某些jscss文件非常大并且需要一些时间来加载时)?我尝试过操作 DOM(在我看来,在文档准备好之前这样做是不正确的)并document.body导致null.

额外的

设置间隔的解决方案来自这里。非常感谢任何其他关于如何做到这一点的想法。

4

5 回答 5

4

如果是我,我可能会尝试这样的事情:

<style>
.notification {
  font-family: sans-serif;
  font-size: 11pt;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  padding: 30px;
  text-align: center;
  background: #eee;
  -webkit-opacity: 0;
  -moz-opacity: 0;
  -ms-opacity: 0;
  -o-opacity: 0;
  opacity: 0;
  -webkit-transition: all 1s;
  -moz-transition: all 1s;
  -ms-transition: all 1s;
  -o-transition: all 1s;
  transition: all 1s;
}
.notification.reveal {
  -webkit-opacity: 1;
  -moz-opacity: 1;
  -ms-opacity: 1;
  -o-opacity: 1;
  opacity: 1;
}
</style>

紧随其后的以下标记<body>

<div id="note-wrap"></div>

以及之前的以下标记</body>

<script>
  (function(){
    var gui = {}, tos = {};
    gui.wrap = document.getElementById('note-wrap');
    gui.note = document.createElement('div');
    gui.note.className = 'notification';
    gui.note.innerHTML = 
      'The page is taking a long time to download. ' + 
      'Please continue waiting.'
    ;
    /// run the setInterval at 30s
    tos.append = setInterval(function(){
      /// add the note element
      gui.wrap.appendChild(gui.note);
      /// trigger the css transitions
      tos.reveal = setTimeout(function(){
        gui.note.className = 'notification reveal'; delete tos.reveal;
      }, 100);
      tos.conceal = setTimeout(function(){
        gui.note.className = 'notification'; delete tos.concel;
      }, 5000);
    }, 30000);
    /// on dom ready clear timeouts
    jQuery(function(){
      clearInterval(tos.append);
      if ( tos.conceal && tos.reveal ) {
        clearTimeout(tos.reveal);
        clearTimeout(tos.conceal);
      }
    });
  })();
</script>

通过将此脚本放在关闭正文标记之前,您可以访问所有以前解析的 DOM 元素,您无需等待 DOMReady。

虽然,为了触发这一点,您需要一个非常大的页面,因为它必须只是纯粹的 dom 渲染,从而减慢页面速度。

是否有任何其他可能的方式来通知用户页面加载缓慢(特别是当头部中的某些 js 或 css 文件非常大并且需要一些时间来加载时)?

以上使我相信您最好使用jQuery(window).load而不是jQuery(document).ready. 因此,您可以将上面的后半部分替换为:

/// on everything ready clear timeouts
jQuery(window).load(function(){
  clearInterval(tos.append);
  if ( tos.conceal && tos.reveal ) {
    clearTimeout(tos.reveal);
    clearTimeout(tos.conceal);
  }
});

这只会在所有内容(即图像、脚本、样式等)下载后触发。

没有 jQuery

这也很容易以跨浏览器的方式实现——比 DOMReady 更容易——无需使用 jQuery。我们只需要确保我们不会消灭任何预先存在的onload听众。

window.onload = (function(prev, ours){
  return function(e){
    ( ours && ours.call && ours.call( window, e ) );
    ( prev && prev.call && prev.call( window, e ) );
  };
})(window.onload, function(){
  clearInterval(tos.append);
  if ( tos.conceal && tos.reveal ) {
    clearTimeout(tos.reveal);
    clearTimeout(tos.conceal);
  }
});

但是,如果您想要一个更现代的解决方案,只需担心您可以使用的顶级浏览器:

window.addEventListener('load', function(e){
  clearInterval(tos.append);
  if ( tos.conceal && tos.reveal ) {
    clearTimeout(tos.reveal);
    clearTimeout(tos.conceal);
  }
});

...并添加了一些跨浏览器,可能类似于:

var onload = function(){
  clearInterval(tos.append);
  if ( tos.conceal && tos.reveal ) {
    clearTimeout(tos.reveal);
    clearTimeout(tos.conceal);
  }
};

if ( window.attachEvent ) {
  window.attachEvent('onload', onload); // note the 'on' prefixed
}
else if ( window.addEventListener ) {
  window.addEventListener('load', onload);
}

然后你就有了一个快速的、无库的解决方案,它不依赖于警报对话框。

于 2013-09-06T08:31:12.103 回答
1

一个可能的(但有点混乱的解决方案):

在 iFrame 中加载您的页面并将准备好的事件侦听器附加到 iFrame。这是如何执行此操作的示例

jQuery .ready 在动态插入的 iframe 中

通过这种方式,您可以控制外部页面的 DOM,同时监控 iFrame 加载时间。

于 2013-09-06T05:45:36.267 回答
0

好吧,经过几个小时的伤脑筋,我找到了解决办法。这更多是关于更好的用户体验,而不是技术创新,但符合我的需求。

<script></script>仍然在顶部,<head></head>每 30 秒询问用户是否想留在页面上并等待,直到它加载。如果用户拒绝,则窗口关闭,否则继续加载。该脚本如下所示:

(function () {
   var SLOW_CONNECTION = setInterval(function () {
      if (!confirm("The Internet connection speed is low. Do you want to continue waiting?")) {
         var win = window.open("", "_self");
         win.close();
      }
   }, 30000);
   window.addEventListener("load", function () {
      clearInterval(SLOW_CONNECTION);
   });
})();
于 2013-09-06T13:05:19.847 回答
0

Document-Ready 表示 DOM 已被读取。您可以使用以下方法在 Document-Ready 之前执行代码:

   ...
  </body>
  <script>window.clearInterval(GLOBAL_INTERVAL);</script>
</html>

这是更底层的,你不应该在这里使用 jQuery。

于 2013-09-06T05:45:51.103 回答
0

如何检查document.readyState

  setTimeout(function(){ 
    //after 3 seconds if the document is still not ready the alert will appear
    if(document.readyState=="loading")
     alert("The Internet connection is slow. Please continue waiting.");},3000);

  $(function () {
       alert("document ready");
  });

https://developer.mozilla.org/en-US/docs/Web/API/document.readyState?redirectlocale=en-US&redirectslug=DOM%2Fdocument.readyState

于 2013-09-06T05:53:33.357 回答