I hope this is a question I can ask here ; I know there are rules.
This site https://mylisting.27collective.net/my-city/ (a demo site for a wordpress theme) has a spinner which is visible during page changes.
It seems to me that the browser is restricted from clearing the screen, or beginning to paint the new screen, until some event occurs. The result is that the spinner works beautifully and even on a slow connection the user never sees so much as a flicker between pages.
Can anyone shed any light on how this is achieved?
Many thanks in advance,
This is actually pretty simple. There's a div (main-loader) that sits over the top of the site (the spinner), when the DOM ready event fires, the loader div fades out....
Looking at the code of that page it's simply the below...
jQuery(document).ready(function(e) {
e(".main-loader").fadeOut(750), // <-- This is the loader div
// .....
}
I have a page that loads images from various sources. Occasionally these images fail to load; perhaps the link has gone dead or whatever. That's fine.
What bothers me is that the browser might take 6 seconds or even longer (I've seen 20 seconds) before it decides that the image has failed to load. During this time the spinning loading wheel in the Chrome tab keeps going and going, making it seem like my page isn't ready.
I've switched my javascript loading from onload to $(document).ready() so at least my page isn't inactive while it waits for the images to load. But it might appear as though it is.
But is there some way to make my page appear "ready" (no spinning wheel) when all it's doing is waiting for the image? Maybe another way to load images? I currently use the img element with src. Or a way to make it give up sooner? Does it really need 6 seconds to decide that an image link is dead?
Not sure if this has a solution. It's a problem that I have seen on a lot of websites, not just mine, but it drives me nuts. I'll often click the stop-loading-x just to make it stop! I'd at least like for my own website to not be like that.
According to my tests, the loading indicator in Chrome does not show for image elements where the loading was triggered by Javascript. Thus, if you don't mind the images not loading with javascript disabled, you could send the img with the src unset, and set it when the page loads. You can store the URL in data-src. The upside is then that you can control when the image loads, if you want to (though you may want to use a plugin for that, like Roullie's answer suggests).
<img width=100 height=100 class="async-img" data-src="http://www.example.com/some.png">
...
$(document).ready(function(){
$(".async-img").each(function(){
this.src = $(this).data("src");
})
})
maybe it can help. lazyload.js
Is there a bit of technology available that displays a Lightbox AJAX 'Spinner' in the centre of the page each time the user navigates from one page on a site to another?
So on each 'click' of a hyperlink it would popup a spinner animation while the page loads.
Is this easy to achieve?
Many thanks for any pointers.
There are a few examples out there, the one that springs to mind is BlockUI though. Take a look at http://jquery.malsup.com/block . You will need to combine this with your ajax succes/error/always callbacks, but the examples should help you in the right direction.
You could use .ajaxStart() and .ajaxStop()
$(document).ajaxStart(function() {
$('#spinner').show();
})
.ajaxStop(function() {
$('#spinner').hide();
})
In Google Chrome, AJAX called within $(function(){....}); seems to keep the page loading.
I have a site with a few pages with tabs. Because I'm using cheap godaddy hosting, I want the page to load as fast as possible. I thus want to load a page on 1 tab and then in the background use AJAX to load the other tabs. When I run AJAX from
$(function(){
/*AJAX CODE HERE */
});
The cursor shows the page as loading for a long time (http://jsfiddle.net/mazlix/7fDYE/9/)
I have figured out a way (in chrome atleast) to somewhat fix that using setTimeout(); (http://jsfiddle.net/mazlix/7fDYE/8/), but this only works if you correctly predict when the window finishes fully loading and obviously makes it take longer to load. I want a way to load content via AJAX immediately after the page loads, so no "busy-cursor" is displayed while waiting for the returned AJAX.
Google Chrome shows Loading Indicator as long as there are no new queries to servers. While the loading indicator is shown, all new requests are causing Chrome to extend the time the indicator is shown. Furthermore, when esc is pressed while the indicator is shown, all requests are aborted! These include AJAX requests and even Flash requests! Take a look at this question: i thought it was because of Youtube, but it turned to be Chrome's usual behavior.
The only way to avoid "extending" the time Loading indicator is shown, is making the requests after the loading indicator is hidden: i.e. when all queries to server are completed. JQuery's documentation on .load() says:
The load event is sent to an element when it and all sub-elements have been completely loaded. This event can be sent to any element associated with a URL: images, scripts, frames, iframes, and the window object.
So, if you're sure that there are only images, scripts and frames on your page, window.load() will be fired just when you need it. Adding setTimeout() to it will work as you like. Here is an example: http://jsfiddle.net/7fDYE/22/
If there are other requests being made before your request, you should wait for them to be completed! For example, you know that besides the images/scripts etc. you have 3 more AJAX requests before the page loads. You can have something like this:
var loaded=0,needsToBeLoaded=4; //3 AJAX + window
function onLoad(){
loaded++;
if(loaded==needsToBeLoaded){
//do the AJAX request
}
}
window.load(onLoad);
// add onLoad() to all 3 AJAX request handlers
I'm not sure what you can do with Flash requests...
Update
This solution will not work for Chrome. It stops the loading indicator only when all requests made before window load have completed. The only solution appears to be to get it to make the request after window load, but as far as I know, this is only possible with setTimeout, which isn't great.
Update
To get around the pointer issue in Chrome, you could set the cursor style as shown in this fiddle. It's a bit hacky and it doesn't address the issue of the loading indicator at the top of the tab.
The loading indicator will be present in browsers until the page has loaded (window's load event). In $(function(){someCode();});, someCode is executed when the DOM load event is triggered (when all content has been parsed and inserted into the DOM, before page load). The execution of JavaScript at this point blocks the window's load event from firing, and so prevents the loading indicator from stopping. Note that image loading also blocks the window's load event.
Instead, you could try $(window).load(function(){someCode();});. In this example, someCode is executed when the window's load event is triggered. This is at the point where the browser's loading indicator stops.
So, instead of:
$(function(){
/*AJAX CODE HERE */
});
Try:
$(window).load(function(){
/*AJAX CODE HERE */
});
Note that this may cause your JavaScript to begin execution later, which may not be desirable.
There is a super simple, fool proof solution to this:
Wrap your function in a setTimeout call, and use an interval of 0. This will queue the function to be called immediately, but Chrome will no longer wait for it to load before considering the page 'complete'. You do NOT need to make any guesses about when the page will be complete, just make sure you're calling setTimeout inside the jquery Ready handler, like so:
$(window).load(function() {
setTimeout(function() {
$("#result").html(ajax_load);
$.post("/echo/json/", {json: json1, delay: 10000}, show_json, "json");
}, 0);
});
According to JQuery docs, no javascript should be run till ready for example
$(document).ready(function() {someCode();});
with that in mind i changed your jsFiddle (it takes some time to load but it works)
Edit: hadnt forked jsfiddle ><
I'm not sure I agree that this is a problem. I'd say this is a desirable behavior from chrome as it indicates that it's in fact not finished loading. I would say that Firefox is actually incorrect about not indicating that it's still waiting for a script callback to finish.
This could be a matter of personal taste (I like the browser to indicate that it's waiting/working, even if it makes my browser seem slow), in which case succeeding in "fixing" this "problem", will make the browser not behave in the way the user is used to. In web development you really should not try to force the browser to behave in a specific way that is not essential to how the webapp works, because you're likely to end up enforcing a look-and-feel from one os you're used to into another os with a different feel, making it feel more foreign to the users of another os (even if it makes the site feel more native to you).
The busy cursor is not a problem anyway, because elements already loaded, are still responsive.
Looks like this is a Chrome issue and they are not fixing it:
https://bugs.chromium.org/p/chromium/issues/detail?id=26723
I have a site which uses largeish (60-100k) background images which vary from page to page.
When the user loads the page for the fist time, the page content is loaded first and the background image appears a short time after. This is, I understand, intended behavior in browsers but it makes the page loading look quite "bumpy" on slower connections.
I had thought of hiding the page with a loading "mask" which gets removed by JS when the background image has loaded...but this is still quite an ugly approach.
How could I make it so the page content and the background image appear to the user at the same time?
The best solution here would be to try and find a way to get that image smaller. There are some good compression tools out there. I recommend looking at ImageMagick, some JPEG-specific tools (http://jpegclub.org/) or PNG-specific tools (http://www.aboutonlinetips.com/optimize-and-compress-png-files/).
But to do what you're specifically asking - hide everything on the page until it's ready and then have it load in - you could use jQuery and do something like this:
$(function(){
var bgimage = new Image();
bgimage.src="{your giant image's URL goes here}";
$(bgimage).load(function(){
$("body").css("background-image","url("+$(this).attr("src")+")").fadeIn();
});
});
What this does is it waits until all the elements are loaded on the page and then creates a new Image object. We point the source to your larger image file. When that is finished loading, we change the background to use this newly loaded image, which should load instantly because the browser cached it.
I have fadeIn() there in case you want to hide all of the content on the page until it's ready. This means you should make the hidden.
For some reason fadeIn() works better than show() or simply removing a "hidden" class via removeClass(), if you take that approach. With the latter two approaches the tag seems to resize its height to fit the content of the page which can result in not displaying the background image in its entirety.
Honestly though, I don't really recommend this approach :p
At least, not if you're going to hide all the content on the page until it's ready.
This might be a good approach for displaying the background image only when it's ready, avoiding the partially loaded image being displayed...
A slower load is just the tradeoff for using large images.
A better way would probably be to use jquery and fade the background image in once it has loaded. Also you could try preloading the next image before the user clicks the next page to make it even smoother.
If you delay the content from showing until the image has shown it's just going to irritate your users. They are (probably) there primarially for the information so don't ever touch anything that delays that process.
The exception for this is some arty farty website where people who don't know about websites come on to click on things and they don't care about anything apart from it looking pretty.
You could use data URIs to mitigate this issue in modern browsers and fall back to your current technique for IE 6/7.