I populate many parts of my website using
$("#theDivToPopulate").load("/some/api/call.php", callBackToBindClickEventsToNewDiv);
Where /some/api/call.php returns a built list, div, or some other HTML structure to place directly into my target div. The internet has been running slow lately and I've noticed that the time between a button click (which kicks off these API calls) and the div populating is several seconds. Is there an easy way to globally wrap all the load calls so that a div containing "Loading..." is displayed before the call is even made and hidden once the API call is complete.
I can not simply put the code to hide the div into the callBackToBindClickEventsToNewDiv as some load events have different call backs. I would have to copy the code into each function which is ugly and defeats the purpose. I want the flow of any .load to go as follows:
1) dispplayLoadingDiv()
2) Execute API call
3) Hide loading div
4) do callback function.
The loading div must be hidden first as the callback contains some animations to bring the newly loaded div in nicely.
EDIT:
Expanding on jacktheripper's answer:
var ajaxFlag;
$(document).ajaxStart(function(){
ajaxFlag = true;
setTimeout(function (e) {
if(ajaxFlag) {
hideAllDivs();
enableDivs(['loading']);
}
}, 500);
}).ajaxStop(function(){
ajaxFlag = false;
var load = $("#loading");
load.css('visibility','hidden');
load.css('display','none');
load.data('isOn',false);
});
This way loading is only displayed if the page takes more than 500 MS to load. I found the loading flying in and out real fast made things kind of choppy for fast page loads.
Use the following jQuery:
$(document).ajaxStart(function(){
$('#loader').show();
}).ajaxStop(function(){
$('#loader').hide();
});
Where you have an element called #loader that contains what you want to show when an AJAX request is being performed. It could be a span with text, an image (eg a gif), or anything similar. The element should be initially set to display: none
You do not even need to call the function anywhere else.
Try this
$("#someButtonId").click(function(e){
e.preventDefault();
$("#theDivToPopulate").html("Loading...");
$.get("/some/api/call.php",function(data){
$("#theDivToPopulate").fadeOut(100,function(){
$("#theDivToPopulate").html(data).fadeIn(100,function(){
//Do your last call back after showing the content
});
});
});
});
Related
I've made a loading "animation.gif" for my dynamic website. This is the code I used from jquery, to show and hide the spinner:
$("#loading").bind("ajaxSend", function(){
$(this).show();
}).bind("ajaxComplete", function(){
$(this).hide();
});
http://docs.jquery.com/Ajax_Events
My Problem:
The website has different contents (like flash, images, text etc.). So some parts of the website take longer to load then others. But the duration of loading animation is always the same(its too fast). When I load a content with a flash(4mb) and html text, the spinner hides way too fast, and the content is still loading. The same with HQ images..
I could use a min delay, like:
$("#this").delay(600).fadeOut("slow");
But I dont think this is a good solution at all.
How is it possible not to hide the loading-spinner, until the whole content is loaded?
What you can is create a list of flags for all of the slow loading elements in your page.
Then start listening to each of the elements load event ( You can do it with flash as well ).
Each time an element is loaded raise its flag.
Have a interval run in the background that watch this list, once all of list items are raised, remove the loading-spinner.
You can also try this:
var iv = setInterval(function () {
if (document.all["theObject"].readyState == 4) {
clearInterval(iv)
alert("Object loaded (maybe).")
}
}, 100)
taken from : http://www.webdeveloper.com/forum/showthread.php?160792-lt-object-onload,
by Orc Scorcher
From the very page you linked to, just bind to ajaxStart and ajaxStop instead, which have the required logic built-in and only fire for the first AJAX request in any group, and when the last AJAX request completes.
Alternatively, you can use your own counter to figure out how many AJAX requests are outstanding:
(function(sel) {
var count = 0;
$(sel).bind("ajaxSend", function() {
if (count++ === 0) {
$(this).show();
}
}).bind("ajaxComplete", function() {
if (--count === 0) {
$(this).hide();
}
});
})('#loading');
Ok I tried out this one (Fiddle Here) and hope is what you're looking for.
Basically:
give each element you want the loader to wait for a .content class
dynamically set content src with your jQuery/AJAX whatever
bind $('.content') elements to a .load() event
when .load() is fired increment a counter, if the counter equals the .length of $('.content') selector then hide the loading gif
From jQuery Site about .load() event :
This event can be sent to any element associated with a URL: images, scripts, frames, iframes, and the window object.
So it should work fine with your lazy content.
Hope it helps!
I'm working on a project, which in some cases requires to hide all small text (eg. less than 12px), and on some other event, bring them back. It's not a website, but something happening on the webkit browser. I don't have control over the content on the page (developed by the third party developers), but have control to modify it. I know I can loop through all tag elements and check font sizes and hide them if smaller than 12px, but it's not only inefficient, but the text can be changed to be shown again, say after an ajax call, which is "prohibited". Other solution would be to run that loop every couple seconds, but it's an expensive process.
Other task is to show small text on some other event, which is not too difficult to implement by just using simple custom class.
You can run the code on page-load, and then when any AJAX call completes using jQuery's Global AJAX Event Handlers: http://api.jquery.com/category/ajax/global-ajax-event-handlers/
$(function () {
function findSmallText($root, state) {
if (typeof $root == 'undefined') {
$root = $(document);
}
if (typeof state == 'undefined') {
state = 'none';
}
$.each($root.find('p, div, span, font, button, a'), function () {
if ($(this).css('font-size').replace(/(px|pt|em)/gi, '') <= 12) {
$(this).css('display', state);
}
});
}
//run the function when the DOM is ready
findSmallText();
//also run the function when any AJAX request returns successfully
$(document).ajaxSuccess(findSmallText);
});
You can pass the findSmallText function two arguments:
$root: (jQuery object) the root element to start looking for small text, limit this as much as possible to increase performance (so unnecessary elements don't have to be scanned).
state: (string) the display property to add to the elements with small text, you can use block to show the elements.
if the HTML structure doesnt change (no extra containers added thru AJAX) simply analyze the page onLoad (kinda like what Jasper suggests) but instead of re-running the analysis after each AJAX call you add a new class - let's call it .HideMeInCertainCases for the fun of it. That way you can hide / show everything you want with a simple selector whenever you want.
So instead of this line: $(this).css('display', state); use $(this).addClass('HideMeInCertainCases');
When the event you were talking about occurs you can then toggle the display state with this selector $("HideMeInCertainCases").toggleClass("hideMe"). Changing the display-attribute directly might break your layout as the nodes containing text might have different displays to begin with (block, inline, inline-block...). Of course .hideMe { display:none; } should be somewhere in your stylesheet. If you want the layout to stay the same and only hide the content use visibility instead of display
I am developing an app using jquery mobile..
In that i want to show something like progress dialog from one page to another.
I have tried
$.mobile.showPageLoadingMsg();
but it takes a specific amount of time while showing...
Actually my other page loads few graphs so it takes time...
How can we show progress as soon as the graph loads on the other page?
I think You can make use of the events like pagebeforecreate or pagecreatelike
And placing the $.mobile.showPageLoadingMsg() in proper place in the code can place major thing.
$('#aboutPage').live('pagebeforecreate',function(event){
alert('This page was just inserted into the dom!');
});
$('#aboutPage').live('pagecreate',function(event){
alert('This page was just enhanced by jQuery Mobile!');
});
You can go though the follwing like :
http://jquerymobile.com/demos/1.0a3/#docs/api/events.html
Surround it in
$(document).ready(function() { ... }
if you aren't already
If you use AJAX to switch between pages you can do the following:
jQuery.ajaxSetup({
beforeSend: function() {
$('#loadingDiv').show()
},
complete: function(){
$('#loadingDiv').hide()
},
success: function() {}
});
"loadingDiv" is your container with spinner gif image (for example).
I am struggling with jQuery for a long time now. It is very powerful and there are lot of great things we can do with jQuery.
My problem is that I use a lot of jQuery features at the same time. E.g. I have a site that displays items, 12 items per page and I can paginate through the pages using jQuery. On the same page I implemented a thumpsUp button that uses jQuery too.
The more jQuery features I use, the harder it gets to arrange them properly. E.g.:
$(document).ready(function() {
$(".cornerize").corner("5px"); //cornerize links
$('a#verd').live('click', exSite); //open iframe
$("a.tp").live('click', thumpsUp); //thumps up
$("a#next").click(getProgramms); //next page
$("a#previous").click(getProgramms); //previous page
//for the current page reload the content
$("a#page").each(function() {
$(this).click(getProgramms);
});
//this isn't working...
$('.smallerpost').live('click', alert('test'));
});
Have a look at the last code line. I want to perform an alert when the div element is clicked. Instead of doing so the page shows me the alert when I refresh the page. A click on the div has no effect.
What am I doing wrong? What would be a strategy here to have clean and working jQuery?
Change that line to
$('.smallerpost').live('click', function () {
alert('test');
});
and while you're there...
$("a#page").each(function() {
$(this).click(getProgramms);
});
has exactly the same effect as:
$('a#page').click(getProgramms);
... but technically there should be only one element with id='page' anyway
Your code $('.smallerpost').live('click', alert('test')); calls the alert immediately and passes its return value into the live function as the second parameter. What you want to pass there is a function to call, so you want:
$('.smallerpost').live('click', function() {
alert('test');
});
or
$('.smallerpost').live('click', handleSmallerPostClick);
function handleSmallerPostClick() {
alert('test');
}
...depending on how you structure your code.
I am using a jQuery ticker which is pretty cool. It works well with predefined content, but I want to build my tags dynamically by getting the data from a feed via the $.ajax method.
http://progadv.uuuq.com/jStockTicker/
The problem is when I do this the ticker wont work, as it looks like the function might be loading before my page content has loaded. Can anbody think of a way around this?
$(function() {
$("#ticker").jStockTicker({interval: 45});
});
$(document).ready(function() {
$("#ticker").jStockTicker({interval: 45});
});
You need to call the jStockTicker function from within the success method with the Ajax call, because like you say, jStockTicker is calculating the dimensions for scrolling before the content has been added to the page.
$.ajax({
url: 'ajax/test.html',
success: function(data) {
//Populate $('#ticker') with data here, e.g...
$('#ticker').html(data);
//Now call jStockTicker
$("#ticker").jStockTicker({interval: 45});
}
});
Something like that ought to do it.
Rich
I have never used the jStockTicker; however with another plugin you can change the data dynamically. For example for the jQuery webTicker you can simply replace the content with the list items using javascript and the rotation will continue without halt. I have used this method on a financial website and works like a charm updating the data every few seconds to show the latest exchange rates. The scrolling and dimensions id done automatically per item; once it moves out of screen it is popped back in at the end of of the list. So the list should not break at any point in time
$("#ticker").jStockTicker({interval: 45});
from calling the jStockticker inside success method the scrolling stops and restarts from the begining.