I'd like to display content once everything is available and correctly positioned in the web page. Most preloader techniques only consider download time, not rendering time, therefore letting the user seeing the page being constructed. That's short, but clearly noticeable. I'm using WebKit inside a native app, but that shouldn't matter.
What is the correct approach to delay content display until the page is completely ready?
As mentioned above, you can initially style everything to be visibility:hidden
<div id="content" style="visibility:hidden">
<!-- all your content
(won't be displayed, as long as they are not explicitly
visibility:visible) -->
</div>
The javascript to un-hide everything is quite simple:
function unhide() { document.getElementById("content").style.visibility = ""; }
To call it when everything is loaded, use the load event:
document.addEventListener('load', unhide, false);
I think the jQuery ready() handler actually listens to the DOMContentLoaded event in modern browsers, so it'll run before your images are loaded. If you only need the layout fixed before displaying everything, you can use ready() or DOMContentLoaded, but be sure to explicitly specify the image dimensions in HTML.
Related
I use jQuery (which seems to use a glorified form of innerHTML document writing), to add a piece of HTML to the DOM:
$newElem=$(HTML).appendTo($container);
The said HTML piece contains CSS links, which seem to load async. Images also load async.
I need some form of load event similar to window.load when async content is done fetching AND done parsing (i.e. CSS), because based on that I trigger a container resize/rearrange function, and sizing obviously depends on CSS, async images (and even async fonts but this last point is not an immediate concern for me). So how to get a proper load event for the DOM-added HTML?
I don't think there's a built-in "load" event that's fired when all the resources requested by the dynamically added elements are finished loading.
You can probably implement this though if you're sufficiently motivated.
There's waitForImages jQuery plugin, that goes through the given DOM subtree, looking for images (<img> tags as well as references to images in computed CSS styles). It creates an <img> element for each image referenced from CSS to track its load status (as discussed here).
It doesn't support:
content:url() images (should be easy to add)
Tracking resources referenced from dynamically loaded CSS. You can use a similar approach to find all the <link> elements in the given subtree, and use their load event (supported in all major browsers now) to wait until the CSS is loaded. After CSS finishes loading, run waitForImages to track the image loads.
I am trying to hide my preloader with JavaScript once the DOM and at least the top content has been loaded. The problem is that my page has several iframes which can slow the process down a lot.
My understanding is that if I use jQuery's $(document).ready to hide the preloader, it will be hidden too soon. On the other hand, if I use $(window).load, the waiting time may be too long. So, is there a middle-way solution, - kind of like window.load but without waiting for iframes?
EDIT:
My page has stuff like Facebook Like button Google Translate and a few other scripts that work via iframes. These are not critical elements, and I would not like to wait for them to load fully.
On the other hand, CSS files like Bootstrap, jQuery, etc. are curcially important for the presentation, and therefore to show the page (hide preloader) w/o having these loaded first would be premature.
Thanks.
You could use $(document).ready to determine if a particular element is loaded before hiding your loader.
Or if you have partial views, to have a $(document).ready function in one of those pages js do the loader hide job.
Since you did not provide more info, these are closer to guesses than real solutions.
I think you're looking for document.onload, which will fire when the DOM tree is ready. I believe that it fires before iframes, which all get their own onload callback/event handler.
You can also try placing the script tag at the end of your html file without begin inside an onload or ready function. This will cause it to load the html content, then fire the Javascript.
EDIT
A thought just occurred to me, which may or may not be useful. You probably have an idea about when you want your script to execute. In whatever browser you are using, check the network tab of the development console. There may be some other element's onload function you want to wrap your code in. For example, if you have a background image you want to make sure loads before your code executes, you may want to use it's onload.
As Petre said, lack of info in the question makes answering difficult.
I have a website with a background and a main container. I wanted to hide the container until the whole page has been loaded. so i added
#cover{opacity:0}
at the start of the page and
$(window).load(function() {
$('#cover').css('opacity','1');
});
at the end, just before </body> tag. It works perfectly when page is loaded for the first time.
PROBLEM : If I load the same page once more, it shows all the images and text scattered throughout the page. It works fine once completely loaded. certainly this type of behavior is caused by cached images. but all the images are inside the main container which has opacity:0, This has completely confused me.
UPDATE 1:
I am using turn.js to convert the whole container into a book, i want the book become visible when the book is ready i.e. both loading of images and javascript initialization has completed.
UPDATE 2:
This is how i am checking for "images loaded" and "javascript initialized". it worked as i wanted it to. is this a good way to handle the situation?
$(window).load(function(){
$(window).ready(function() {
$('#cover').css('opacity','1');
});
});
$(window).ready(function(){
$(window).load(function() {
$('#cover').css('opacity','1');
});
});
The problem may be related to your $('window').onload();
Take some time and read this SO post.
what-is-the-difference-between-window-load-and-document-ready
load is called when all assets are done loading, including images.
ready is fired when the DOM is ready for interaction.
From the MDC, window.onload:
The load event fires at the end of the document loading process. At
this point, all of the objects in the document are in the DOM, and all
the images and sub-frames have finished loading.
From the jQuery API
documentation, .ready( handler ):
While JavaScript provides the load event for executing code when a
page is rendered, this event does not get triggered until all assets
such as images have been completely received. In most cases, the
script can be run as soon as the DOM hierarchy has been fully
constructed. The handler passed to .ready() is guaranteed to be
executed after the DOM is ready, so this is usually the best place to
attach all other event handlers and run other jQuery code. When using
scripts that rely on the value of CSS style properties, it's important
to reference external stylesheets or embed style elements before
referencing the scripts.
Let me know if this change works.
You do not call the same block in your CSS (#container) and in your JS (#cover).
I am looking for a way to modify some text inside the HTML before it is being parsed by the browser.
More precisely, I would like to remove some tags from the HTML so the image resources would not be fetched by the browser, only when I am ready I could insert these tag back to have them loaded.
Is it possible to do that via some JS/Jquery or CSS, if so, how?
the motivation here is to be able to block the loading of some resources on a page and have them loaded only when needed according to some logic. this needs to be done by some kind of scripting added to the page
Because you're doing this in JavaScript the HTML is already being processed when it comes to launch your <script> tags.
You could move your <script> tags into the <head> from the <body>, or move it to the very beginning of the body. However the problem here is that you'll have to wait for your elements to actually be created in the DOM before you can work with them.
You could use something like setTimeout() or similar and continually look for them until you find them, but there's still going to be a slight delay between them being created and your script finding them, at which point they might already start to load.
The only surefire way is to process the markup server side long before it gets to the browser.
My answer here possibly could be of use, if you can place noscript tags in key places in your markup prior to parsing/evaluation:
Client-Side Dynamic Removal of <script> Tags in <head>
This method—for javascript-enabled agents—would delay the rendering of the entire page however, or at least the regions that you needed to affect.
basic generalised theory
Wrapper your body or specific region with a noscript tag identified with either a class or id. Place some javascript to execute directly after the close noscript that grabs the tag and reads the html contents as a string. At this point you could modify the html string however you like and then re-inject it back into the DOM replacing the noscript tag.
more specific implementation
If you know before-hand which resources you need to postpone—say all your images—you could wrap each image in-question with a noscript tag. Then trigger off some JavaScript that grabs all noscripts and rewrites the contained image html to use a placeholder or lower quality version of the image. At the same time you could set up event listeners or timeouts that inject the actual images when the time is right.
The Lazy Load Plugin for jQuery is maybe what you are looking for. It delays loading of images in long web pages.
You can use any jQuery event such as click or mouseover. You can also use your own custom events such as foobar. Default is to wait until user scrolls down and image appears on the window.
Beside all the It is also possible to delay loading of images. Following code waits for page to finish loading (not only HTML but also any visible images). Five seconds after page is finished images are loaded automatically.
$(function() {
$("img:below-the-fold").lazyload({
event : "sporty"
});
});
$(window).bind("load", function() {
var timeout = setTimeout(function() {
$("img.lazy").trigger("sporty");
}, 5000);
});
Check the delayed loading demo.
So I'm using jquery along with some plugins I wrote.
I do all the initialization in a $(document).ready(function(){}) block however this is executed when the whole DOM has been loaded and is ready to be used.
However that would take long eg. when there is a server load. Or maybe the user clicks a button that has been loaded while the rest of the page hasn't loaded yet (and thus document.ready() hasn't been executed yet) in which case it would do nothing.
So, what if I want a code to be executed right after the related part of the page has been loaded instead of waiting for the WHOLE page to be loaded?
I know placing inline code right after the html that this js operates on would do the trick but what if that code uses a library like jQuery that hasn't been loaded yet?
I know placing inline code right after the html that this js operates on would do the trick but what if that code uses a library like jQuery that hasn't been loaded yet?
That would be the only way. The HTML is parsed from top to bottom. So you can expect every script you included to be accesible after you included it.
Your page should still work without JavaScript anyway, so a user clicking a button extremely fast will just temporarily have a somewhat degraded experience.
That being said, the DOM is basically ready when the HTML document all scripts are loaded. Since you cannot execute meaningful JavaScript before the JavaScript code is loaded (duh), I'd have a close look at page performance. Sending an HTML document and 2,3 JavaScript files should not be slow.
You could also use the old-style inline event handlers, like <button onclick="registerButtonClickEvent()">. However, this would introduce a complex, potentially buggy and hardly testable layer of temporary event holding.
If your <script src="jquery-whatever.js> line precedes the first clickable element in your HTML, it is guaranteed that the jquery library will be loaded and run before the user has anything useful to click on.
Just don't add async or defer attributes to the script element.
The onload event isn't triggered from all html elements, so you're forced to wait for window load. It doesn't matter where you load jQuery since it will have to wait for document to be ready. That total time required to load jQuery plus the rest of the document will be thet same.