文档准备好之前可能的操作

时间:2013-09-06 04:45:22

标签: javascript html

问题

我写了一个脚本,告知用户页面加载缓慢(比如说,这是因为网络连接速度慢)。该脚本首先放在<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

其他

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

5 个答案:

答案 0 :(得分: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>

通过将此脚本放在close body标签之前,您可以访问所有以前解析过的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);
  }
});

...并添加了一点crossbrowseriness,可能是这样的:

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);
}

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

答案 1 :(得分:1)

一种可能的(但很简单的解决方案):

将您的页面加载到iFrame中,并将一个ready事件侦听器附加到iFrame。以下是如何执行此操作的示例

jQuery .ready in a dynamically inserted iframe

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

答案 2 :(得分:0)

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

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

这是更低级别的,你不应该在这里使用jQuery。

答案 3 :(得分: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

答案 4 :(得分: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);
   });
})();