7

case 1:

I load a very large HTML page that includes a lot of complex layout and fonts. The page will take some unknown time to render.

case 2:

I use jquery .html() function to make significant changes to my DOM. The modified DOM will take some unknown time to render.

In both cases, I want to be able to cover the whole screen with a spinner until the page has completely finished rendering.

In searching for answers to this question, I have found similar questions asked but the answers are not relevant. To be clear:

I don't want to know when the DOM is ready.

I don't want to know when the HTTP data has been fetched.

I want to know when everything in the DOM has been completely drawn to the screen.

Setting some worst-case timeout is not an acceptable solution.

I need a solution for WebKit based browsers.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
GroovyDotCom
  • 1,304
  • 2
  • 15
  • 29
  • The former is easy: Use `onload`. The latter I don't know whether it's possible, interested to see what comes up. – Pekka Dec 21 '10 at 00:15
  • 4
    From a usability standpoint, covering the whole screen with a spinner is IMO the worst thing you can possibly do. It'll just make the long load seem even longer. Just my 2¥. :o) – deceze Dec 21 '10 at 00:16
  • 2
    Can't you just add a spinner to the basic html and than hide the spinner after all the javascript is done? – Mark Baijens Dec 21 '10 at 00:38
  • onLoad doesn't do the job for the first case either according to: http://www.howtocreate.co.uk/safaribenchmarks.html – GroovyDotCom Dec 21 '10 at 00:54
  • @Mark. You missed the point. "hiding the spinner" after the Javascript is done is exactly the problem. The javascript is "done" before page rendering/painting is completed. – GroovyDotCom Dec 21 '10 at 01:23

5 Answers5

2

Just a small point; most browsers won't animate a spinner whilst they're processing the javascript. Particularly the IEs which behave very single-threaded.

It's worth using a different, non-animated, design for the 'spinner'. Something like an hourglass.

Thought for your when's it rendered challenge: why not put something after your initialisation code which you call in your $(document).ready event. In the case of IEs, it should fire last.

GlennG
  • 2,982
  • 2
  • 20
  • 25
  • Can confirm this from experience - you find a beautiful spinner, and then it's just freezed until the page loads - most of the time. – CodeVirtuoso Jan 04 '11 at 17:05
1

Something like this should hopefully work:

...
<head>
  ...
  <style type="text/css">
    #overlay {
      background:url(../images/loading.gif) no-repeat 50% 50%;
      display:none;
    }
    .loading #overlay {
      display:block;
      left:0;
      height:100%;
      position:absolute;
      top:0;
      width:100%;
    }
    .loading > #overlay {
      position:fixed;
    }
  </style>
  <script>
    if (document.documentElement) {
      document.documentElement.className = 'loading';
    }
  </script>
</head>
<body>
  ..
  <div id="overlay">
    ..
  </div>
  <script>
    $(document).ready(function() {
      $('.loading #overlay').fadeOut(500,
        function() {
          $(document.documentElement).removeClass('loading');
          $('#overlay').remove();
        });
    });
</body>
</html>
Ian Oxley
  • 10,916
  • 6
  • 42
  • 49
0

Just off the top of my head, you could do something like this:

var img_loaded;
$(lastImg).load(function () { img_loaded = true; });

(function checkLoading() {
    return $(lastElement).css("lastProperty") === "value" && img_loaded ? stopLoading() : setTimeout(checkLoading, 50);
}());

Of course, there's a lot wrong with this:

  1. It assumes that an Image.onload event works the way it normally does (the image is completely downloaded and everything). If Safari "cheats" on the window.onload, can we trust them with images?
  2. It assumes that the last rule in the CSS file will be carried out (and so completed) last. I would guess that if the last rule is a font-weight or something, and the second-to-last rule is loading a MB background-image, that won't work either.
  3. It requires constant attention. Different parts have to be updated for different pages. As is, it doesn't scale.

The article you linked to only talked about Safari 3. Can we still not trust Safari's onload two versions later?

sdleihssirhc
  • 42,000
  • 6
  • 53
  • 67
0

For case one I think you can use:

<BODY onLoad="alert('Page Fully Loaded')">
Qarib Haider
  • 4,796
  • 5
  • 27
  • 38
0

Set listeners to the complex HTML elements (that may take some unknown time to render), when each of them has loaded, mark it as done and count it, when the event's count equals to the total of elements, we can confirm that the page has completely finished rendering.

ling
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 18 '22 at 03:47