Hide page until everything is loaded Advanced - javascript

I have a webpage which heavily makes use of jQuery.
My goal is to only show the page when everything is ready.
With that I want to avoid showing the annoying page rendering to the user.
I tried this so far (#body_holder is a wrapper inside body):
$(function(){
$('#body_holder').hide();
});
$(window).load(function() {
$("#body_holder").show();
});
This works completely fine, but messes up the layout.
The problem is that hiding the wrapper interferes with the other jQuery functions and plugins used (eg layout-plugin).
So I guess there must be another trick to do this. Maybe lay a picture or div over the body until window.load has occurred?
What approaches do you use?
EDIT:
The solution most likely has to be another way than display:none or hide();

Anything done with jQuery will normally have to wait for document.ready, which is too late IMHO.
Put a div on top, like so:
<div id="cover"></div>
set some styles:
#cover {position: fixed; height: 100%; width: 100%; top:0; left: 0; background: #000; z-index:9999;}
and hide it with JS when all elements are loaded:
$(window).on('load', function() {
$("#cover").hide();
});
Or if for some reason your script uses even longer time then the DOM elements to load, set an interval to check the type of some function that loads the slowest, and remove the cover when all functions are defined!
$(window).on('load', function() {
$("#cover").fadeOut(200);
});
//stackoverflow does not fire the window onload properly, substituted with fake load
function newW()
{
$(window).load();
}
setTimeout(newW, 1000);
#cover {position: fixed; height: 100%; width: 100%; top:0; left: 0; background: #000; z-index:9999;
font-size: 60px; text-align: center; padding-top: 200px; color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>This</li>
<li>is</li>
<li>a</li>
<li>simple</li>
<li>test</li>
<li>of</li>
<li>a</li>
<li>cover</li>
</ul>
<div id="cover">LOADING</div>

Here is a jQuery solution for those looking:
Hide the body with css then show it after the page is loaded:
CSS:
html { visibility:hidden; }
JavaScript
$(document).ready(function() {
document.getElementsByTagName("html")[0].style.visibility = "visible";
});
The page will go from blank to showing all content when the page is loaded, no flash of content, no watching images load etc.

You should try setting visibility to hidden instead of display:none. Setting visibility to hidden will retain all elements positions and dimensions, thus it shouldn't create layout problems.

Start your HTML with:
<body style="opacity:0;">
At the end of your script:
document.body.style.opacity = 1;

Stumbled upon this and tried #9ete's solution but it didn't help me.
This worked instead:
CSS:
html { visibility:hidden; }
JS:
window.addEventListener('load', function () {
document.getElementsByTagName("html")[0].style.visibility = "visible";
});
As per documentation for window, the load event is fired after all the content (images included) is loaded while $document says that ready is fired after only the DOM is ready.

Your question is valid, but I would not get in a practice of hiding or covering the page while things are spinning up.
It keeps the user from understanding what's happening on the page. While lots of things may need to load, different parts of the page should spring to life as they're loaded. You should get in the practice of locking controls that are not ready, perhaps displaying a spinner or some other progress indicator over them. Or setting the cursor to wait on loading items.
This keeps the user in the loop and allows him to see and interact with parts as they come online instead of obscuring all parts until everything is ready.
You will normally want to load the things the user needs the quickest access to, usually stuff above the fold, first. Loading is a prioritization that can easily be coordinated with Promises.
At the very least seeing the page allows the user to get his bearings and decide what to do. Be transparent.

I was seeking a non-javascript solution so I found one that is working on most browsers in acceptable manner.
Since the loading order of CSS rules matters;
Define the hiding class in the first CSS file or inline in head.
.hidden-onpage-load{ display: none; }
In the body, the class can be used as
<div class="hidden-onpage-load"> ... </div>
Redefine it inline or in a CSS file after all other CSS and JS files are loaded
.hidden-onpage-load{ display: block; }

The simplest solution I've come up with is to wrap the body in a as suggested previously, but set it as hidden from the get go, then use JQuery (or javascript) to unhide on load after all components are loaded.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="bodyDiv" hidden>
Hello World!
</div>
<script>
$(document).ready(function() {
// add JQuery widget loads here
$("#bodyDiv").show(); // reveal complete page
})
</script>

Don't forget, a lot of frameworks use javascript to structure a page. To prevent the page from showing before these modification have been made you'll need to do something like what is described here (e.g. run a script at the end of the page to show the real contents of the page):
Detect if any JavaScript function is running

If you have a div #bodyholder then you can put display:none in your CSS for it and then with jQuery do:
$(document).ready(function() {
$('#body_holder').show();
});
I don't see why hiding a div should interfere with the loading of anything, because all it means is it is hidden. However, if you have lots of jQuery being used then make sure you wrap it in $(document).ready which will make sure that the DOM is fully loaded before the Javascript is executed
A further point is that HTML/CSS is designed for progressive loading, and if you do it properly then you can get a nice progressive loading of content for your users. I personally wouldn't want my users getting a white screen for a few seconds until everything was loaded. Move your Javascript to the end of the page so that it doesn't block loading and get content onto the screen as quickly as possible.

Related

javascript: "everything has finished drawing to the screen" event?

Is there a javascript event I can hook into that will let me know when everything has finished drawing to the browser screen? Images, backgrounds, and DOM elements with proper CSS.
I am setting up some "loading..." divs that should disappear only when the page is perfect and ready to be shown to the user.
I am aware of $(document).ready and onLoad, but these are not what I mean.
I am using angularJS, but I dont think this should matter.
thanks!
As you may know, $(document).ready only waits for HTML structure and Javascript to load to trigger.
You better use :
$(window).load(function(){
//do stuff here
});
to wait for everything in your page to load (even pictures)
Though this solution will not trigger any event, it should help you.
Define CSS like this:
#dvLoading
{
background:#000 url(images/loader.gif) no-repeat center center;
height: 100px;
width: 100px;
position: fixed;
z-index: 1000;
left: 50%;
top: 50%;
margin: -25px 0 0 -25px;
}
Use the above in
<div id="dvLoading"></div>
And then do this:
$(window).load(function(){
$('#dvLoading').fadeOut(2000);
});
Demo: http://jsfiddle.net/jquerybyexample/ssqtH/embedded/result/
Source:http://www.jquerybyexample.net/2012/06/show-loading-image-while-page-is.html
Because you're using AngularJS, I can assume that your images and content are mostly loaded dynamically, in which case you cannot (easily) know when exactly all your content is even generated, and hence you'd also have no idea when all your images will be loaded since everything will be loaded asynchronously.
What you could do is have your DOM placeholders for widgets/apps/controllers be set to a loading-like state by default (a loading.gif maybe?) and when Angular generates the content it will just replace it. Look at http://docs.angularjs.org/guide/animations for how to implement animations on certain directives.
Then within those widgets/apps/controllers you would have to do the same thing with the content within them...
So basically it's a cascading "loading screen", where each level of your application loads up like a water fountain.
What is wrong with the $(document).ready or onLoad functionality?
$(window).load(function()
{
$(".loading").hide();
}

Progressively change all images on a page

I have a client who asked to temporarily hide all images on a webpage, but without creating a 404 (leaving them visible to bots).
My try was this:
jQuery(document).ready(function() {
jQuery("img").attr({src: "/my/path/myfile.png"});
});
The problem is that on a slow connection, images are loading, and only on $(document).ready() are hiding (of course - that is what I asked in the code :-) - I do not know a different method …)
How can I make it so that all the images will be "hidden" on browser side, while loading, in a progressive way?
Why don't you simply hide them using CSS:
img {
visibility: hidden;
}
This way all images are linked correctly, your content flow is intact (in contrary of using display: none;), you don't need any JavaScript and the users won't see them.
Demo
Try before buy
There is two ways that I know to do this.
img {
background: url('loading.gif') no-repeat;
}
and
<script>
$('#loadImg').show();
$('#BaseImage').load(function(){$('#loadImg').hide();});
</script>
You assign load event to the image which fires when image has finished loading but background image to all images using css will be easier. Take note that This doesn't work very well with transparent images.

How to load a div with a flash object, but not display it (element loaded, not displayed)

I'm looking for something between display: none and visibility: hidden. In other words, I want for div element (with flash content) to be loaded, but not displayed at all.
To make it more clear: there is a flash object embedded through swfobject.embedSWF in the div. When I change display (via javascript) from block to none and then from none to block, it works different in different browsers:
in IE it works like I want it to work - I change the display to block and the object is still there, but in Chrome and FF it is loaded again, like for the first time when swfobject.embedSWF was called.
how about setting it to
HTML (somewhere on the page)
<body>
<!-- other code -->
<div id="my-div">
<!-- your object / embed code -->
</div>
</body>
in the CSS
#my-div {
left: -9999px;
position: absolute;
}
EDIT: on reading your question again, I understood differently... you want to keep the div out of view... right?
so you can still use on of the below mentioned jQuery calls to show it... but if you want to keep it hidden the above CSS should be enough... still the object should be rendered and loaded
$("#my-div").css({ position: "static" });
// or
$("#my-div").css({ left: 0 });

How to force margins to be ready from js before document ready

I am using an effect a website I have built to detect and move the website from on document ready as well as when the browser window is resized. There is an effect I must address that I did not consider. When the page loads it reads css from the css file and once document is ready it reads from dynamic value provided from js. I was hoping someone can give some insight on how I can read the js value before the css value.
Thank you in advance,
DT
I made this example http://jsfiddle.net/efortis/kUfdE/
First, hide it by default in the CSS with display:none
.orangeBox{
background: orange;
display: none;
}
Then display it with javascript, equivalent to .css('display', 'block') to show the display:none element
$(document).ready(function () {
$('.orangeBox').delay(1500).fadeIn('slow');
});

smooth transition between pages when redirecting with jquery

I am trying to get a smooth transition when I redirect users. First by fading out the page then redirecting and and fadeIn.
Here is my redirect
if ( data.redirect != undefined )
{
$("#toppanel").slideUp(1000);
$("#content").fadeOut(2000, function() {
window.location = data.redirect;
});
My next page has a javascript in the header like this:
jQuery(function ($) {
$("div.container_16").first().hide();
$(".grid_16").first().hide();
$("div.container_16").first().fadeIn(2000);
$(".grid_16").first().slideDown(4000);
This almost work except for a few milli sec where the second page loads then turns blank and fades in. How do I fix this? Do I need to change the css or html?
A simple fix to this would be:
CSS
body{
display:none;
}
JS
jQuery(function ($) {
$('body').show();
$("div.container_16").first().hide();
$(".grid_16").first().hide();
$("div.container_16").first().fadeIn(2000);
$(".grid_16").first().slideDown(4000);
}
You should know that 1 second is a lot of time for a web user. And basically taking 6s extra to just move to another page could be very costly to your user base. I hope you offer a solution without these kind of effects.
UPDATE
CSS
/*
* overflow => so you don't get a scrollbar
* visiblity => so all content is hidden
* background => so you get a black background
*/
.bodyExtra{
overflow:hidden;
visibility:none;
background:#000;
}
JS
jQuery(function ($) {
$(document).ready(function(){
$("div.container_16").first().hide();
$(".grid_16").first().hide();
$('body').removeClass('bodyExtra');
$("div.container_16").first().fadeIn(2000);
$(".grid_16").first().slideDown(4000);
});
}
The logic behind this is to make your page work as a buffer zone. You then hide the elements you want to fade in, remove the class from body and fade everything in.
UPDATE 2013.09.01
I see this answer is still generating some traffic and I have to admit, since the initial answer in 2011, I have an addition to make
HTML/CSS
<noscript>
<style type="text/css">
.bodyExtra{
overflow:auto !important;
visibility:visibile !important;
}
</style>
</noscript>
This can also be done with a <link rel="stylesheet" type="text/css" href="no-js.css" /> tag.
The idea behind this is to fix the disabled javascript issue described by theazureshadow in the comments.
You're getting what is called a "flash of unstyled content" or FUC. You could wrap your second page in a container and hide that via css (display: none;) and then fade in when it's loaded.
Don't use pure css to hide the content originally. If you do, users with JavaScript turned off will not see your content. Instead, only hide when javascript is available.
.js-enabled div.container_16,
.js-enabled .grid_16 {
display: none;
}
Include this line of javascript at the very top of the body:
$(document.body).addClass('js-enabled');
Then in your animation function, after you've hidden .grid_16, include this line to return things to normal:
$(document.body).removeClass('js-enabled');
If you want, you can be more specific and target the hiding styles to the particular elements you want to hide. But I don't know if that's practical for your case -- too few details.

Categories

Resources