Reputation: 3000
I am using jquery get
to load html onto my content div. The HTML I am loading contains some images and I am finding that my custom height calculation I am doing in javascript isn't working too well because the images are fully loaded when the loadHTML
has returned.
var loadHTML = function(){
return $.get("javascripts/templates/" + templateType + ".html", function(text) {
$("#content").html(text);
});
};
Is there a way I can only return from loadHTML
once all images have loaded? I tried to call and return load
but this doesn't work
var loadHTML = function() {
return $.get("javascripts/templates/" + templateType + ".html", function(text) {
var content = $("#content").html(text);
return $('img', content).load();
})
};
Also, I am using Q promises in other parts of my application so is it possible to fix my problem using that.
ie. loadHTML.then(loadImages).then(doOtherStuff);
Upvotes: 4
Views: 108
Reputation: 718
Deleted my other answer because it was too wordy.
The reason your code is not working is because you are making an ajax request to a server, then returning from the function immediately. The page ploughs on with its scripting and probably finishes most if its work before that request comes back with your images.
You need to move your return to a place in your function you know is not going to process until the data comes back. You can use promises to do this:
var jqxhr = $.get( "example.php", function() {
alert( "request sent, images are loading" );
// DON'T PUT YOUR RETURN HERE,
//YOU WANT TO CALL IT WHEN THE ABOVE IS DONE
})
.done(function() {
alert( "the info is loaded" );
//put your html insert here to make sure the
//data is fully loaded before you manipulate it
//you could also call htmlresize here but that would be nesting.
//That shit gets complicated. Just call it after this function returns on success.
return
})
.fail(function() {
alert( "error" );
// its good to handle errors
return
})
if you dont want to hold up your whole page load to load some images you can do facny stuff like put the html resize and other dependent code on the jqxhr.sucess callback, so that other code gets read while your images come through. But that's complicated.
Upvotes: 0
Reputation: 388316
You can try to use a custom deferred object like below
var loadHTML = function () {
var deferred = $.Deferred();
$.get("javascripts/templates/" + templateType + ".html", function (html) {
var $html = $(html),
$imgs = $html.find('img'),
len = $imgs.length,
counter = 0;
$imgs.load(function () {
if (++counter == len) {
deferred.resolve();
}
});
$("#content").html($html);
});
return deferred.promise();
};
TD
var list = [];
for (var i = 0; i < 5; i++) {
list.push('<span><img src="//placehold.it/64&text=' + (i + 1) + '" /></span>');
}
var html = '<div>' + list.join('') + '</div>';
var loadHTML = function() {
var deferred = $.Deferred();
//using a timer to simulate ajax request
setTimeout(function() {
var $html = $(html),
$imgs = $html.find('img'),
len = $imgs.length,
counter = 0;
$imgs.load(function() {
if (++counter == len) {
deferred.resolve();
}
});
$("#content").html($html);
}, 500);
return deferred.promise();
};
loadHTML().done(function() {
$("#content").find('img').each(function() {
$(this).after(this.complete)
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="content"></div>
Demo: Fiddle
Demo: Problem(Change the size of the image to see the problem)
Upvotes: 5