简体   繁体   English

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

[英]Possible actions before document is ready

Problem 问题

I wrote a script for informing user that the page is loading slowly (say, it is because of slow internet connection). 我写了一个脚本,告知用户页面加载缓慢(比如,这是因为互联网连接速度慢)。 The script is put first in the <head></head> and is quite simple: 该脚本首先放在<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);
});

Question

In the current example information is simply alerted. 在当前示例中,仅提醒信息。 Is there any other possible way to inform user about slow loading of the page (particularly when some js or css file in the head is really big and takes some time to load)? 有没有其他可能的方法来通知用户有关页面的缓慢加载(特别是当头部中的某些jscss文件非常大并且需要一些时间加载时)? I've tried manipulating the DOM (which is, in my opinion, is not right thing to do before document is ready) and document.body resulted in null . 我试过操纵DOM(在我看来,在文档准备好之前做的事情是不对的)而document.body导致了null

Additional 额外

The solution with setting an interval is from here . 设置间隔的解决方案是从这里开始的 Any other ideas of how to do that are greatly appreciated. 任何其他如何做到这一点的想法都非常感谢。

If it were me I'd probably try something like this: 如果是我,我可能会尝试这样的事情:

<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>

With the following markup just after the <body> <body>之后使用以下标记

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

And the following markup just before the </body> 以及</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>

By placing this script just before the close body tag you can access all previously parsed DOM elements, you do not need to wait for DOMReady. 通过将此脚本放在close主体标记之前,您可以访问所有以前解析过的DOM元素,您无需等待DOMReady。

Although, in order for this to trigger you'd need a really large page considering it would have to be just pure dom rendering slowing the page down. 虽然,为了触发这个,你需要一个非常大的页面,因为它必须只是纯粹的dom渲染减慢了页面。

Is there any other possible way to inform user about slow loading of the page ( particularly when some js or css file in the head is really big and takes some time to load )? 是否有任何其他可能的方法来通知用户页面缓慢加载( 特别是当头部中的某些js或css文件非常大并且需要一些时间加载时 )?

The above leads me to believe you'd be better off using jQuery(window).load rather than jQuery(document).ready . 上面让我相信你最好不要使用jQuery(window).load而不是jQuery(document).ready So you could replace the latter part of the above with: 所以你可以用以下代码替换上面的后半部分:

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

This will only fire once everything has downloaded ie images, scripts, style and so on. 这只会在所有内容下载后触发,即图像,脚本,样式等。

Without jQuery 没有jQuery

This is also quite easy to implement in a crossbrowser way — more so than DOMReady — without the use of jQuery. 这也很容易以交叉浏览器的方式实现 - 比DOMReady更多 - 不使用jQuery。 We just need to make sure we don't wipe out any pre-existing onload listeners. 我们只需要确保不会消除任何预先存在的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);
  }
});

If you want a more modern solution however, one that only worries about the top tier of browsers you could use: 如果你想要一个更现代的解决方案,那么只关心你可以使用的顶级浏览器:

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

... and with a little bit of crossbrowseriness added, perhaps something like: ...并添加了一点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);
}

Then you have a quick, library-free solution, which doesn't rely on alert dialogs. 然后,您将拥有一个快速,无库的解决方案,该解决方案不依赖于警报对话框。

A possible (but little messy solution): 一个可能的(但很小的混乱解决方案):

Load your page in an iFrame and attach a ready event listener to the iFrame. 将您的页面加载到iFrame中,并将ready事件侦听器附加到iFrame。 Here's an example of how to do this 这是一个如何做到这一点的例子

jQuery .ready in a dynamically inserted iframe jQuery .ready在动态插入的iframe中

In this way you can control the outer page's DOM and at the same time monitoring the iFrame loading time. 通过这种方式,您可以控制外部页面的DOM,同时监控iFrame加载时间。

Document-Ready means the DOM has been read. 文档就绪意味着已经读取了DOM。 You can execute code near before Document-Ready using this: 您可以使用以下方法在Document-Ready之前执行代码:

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

This is more low-level, you should not use jQuery here. 这是更低级别的,你不应该在这里使用jQuery。

how about checking the document.readyState 如何检查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 https://developer.mozilla.org/en-US/docs/Web/API/document.readyState?redirectlocale=en-US&redirectslug=DOM%2Fdocument.readyState

Well, after several hours of hurting the brain, I've came to solution. 好吧,经过几个小时的伤脑,我已经解决了。 This is more about better user experience, than technical innovation, but suits my needs. 这更多是关于更好的用户体验,而不是技术创新,但适合我的需求。

The <script></script> is still at the top of <head></head> , every 30 seconds it asks user, if he wants to stay on the page and wait, until it loads. <script></script>仍然位于<head></head>的顶部,每30秒就会询问用户,是否要留在页面上等待,直到加载为止。 If user refuses, the window gets closed, otherwise loading continues. 如果用户拒绝,则窗口关闭,否则继续加载。 The script looks like the following: 该脚本如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM