Reputation: 9706
I am trying to bring from the server some content using AJAX, I don't know how long it might take to load as some times it might be heavy. So I created a loading gif that appears everytime I call the AJAX function, but I want to fade it out once the AJAX response is loaded and fade in the content division.
HTML
<div id="loading"><img src="loading.gif" /></div>
<div id="content"></div>
This is what I am trying:
$(elm).click(function(){
$('#loading').show();
$('#content').fadeOut();
$.ajax({
url:'posts.php'
data:{id:id_post},
method:"POST",
success:function(response){
$('#content').load(response, function(){
$('#content').html(response);
$('#content').fadeIn();
$('#loading').hide();
});
}
});
});
I know it is wrong because in .load(param1, function(data){})
, param1 should be a reference file to load and not a variable with a string, it seems to work, but console.log(data)
returns me a not found error, so I am sure this is not the way to do it.
In short words: I want to fadeIn() my div and fadeOut() my loading if and only if every byte of the AJAX response is loaded, not if the code is ready, but loaded, for example a big image inside an <img>
tag.
Any ideas? Thanks
Upvotes: 0
Views: 1025
Reputation: 46350
If your AJAX response is a chunk of HTML that includes an <img>
tag that you put on the page, and you want to detect when this image has been loaded, you should do something extra.
You should divide the response in the image to preload, and the raw html that uses the image. You could use a JSON response like this:
{
"image": "url_to_big_image.jpg",
"html": "<img src=\"url_to_big_image.jpg\">"
}
Your favorite backend language probably has a way to convert your objects/arrays to JSON.
Then when your AJAX request has finished, you can do this:
var img = $('<img/>')
img[0].src = response.image // this pre-loads the image
img.load(function() {
// now the image has been pre-loaded
$('#content').html(response.html)
$('#content').fadeIn()
$('#loading').hide()
})
To do this for multiple images you could put the images in an array in the JSON:
{
"images": ["url_to_big_image.jpg", "second_image.jpg"],
"html": "<img src=\"url_to_big_image.jpg\"> <img src=\"second_image.jpg\">"
}
Then loop through them in javascript, and keep up how many have been loaded. If all images have been loaded you can show the content:
var show_content = function() {
// only show content if all images are loaded
if(images_loaded == response.images.length) {
$('#content').html(response.html)
$('#content').fadeIn()
$('#loading').hide()
}
}
var images_loaded = 0
for(var img_url in response.images) {
var img = $('<img/>')
img[0].src = img_url // preload image
img.load(function() { // when image is pre-loaded
images_loaded++ // increase images_loaded
show_content() // show content if all images are loaded
})
}
I haven't tested this code so it might be you need to change something to make it work, but it's about the idea.
Upvotes: 2
Reputation: 74420
You could try this { not tested }:
success: function (response) {
var $tmp = $($.trim(response)),
$l_elems = $tmp.find('img, script'), //find will not work if elements not nested inside a container. In this case use a fake div as container and nesting elements inside it
tot = $l_elems.length,
i = 0;
$l_elems.one('load', function () { //here using one, not on
i++;
if (i === tot) {
$('#loading').hide();
$('#content').append($l_elems).fadeIn();
}
}).each(function () {
if (this.complete) $(this).load();
});
}
Upvotes: 0
Reputation: 46350
The jQuery load
function loads data from a server and takes an url as first argument. See the documentation.
So I think you should just do this:
success:function(response){
$('#content').html(response)
$('#content').fadeIn();
$('#loading').hide();
}
Upvotes: 0
Reputation: 6141
Based on API you could do
$(elm).click(function(){
$('#loading').show();
$('#content').fadeOut();
$('#content').load('posts.php',
{id:id_post},
function(response, status, xhr){
$('#content').fadeIn();
$('#loading').hide();
}
);
});
$.load
already set the html of #content
with the response.
Upvotes: 1