jQuery.load(); not always firing with images - javascript

I have a script which fades in an image when it is loaded to prevent ugly loading animations, which uses the $(elem).load(); function.
My problem is that sometimes there will be a couple of images on the page which haven't been faded in. This is supposedly because the load event hasn't been triggered. I've checked the console for errors, but nothing can be found... It doesn't always happen, but it does on the occasional request.
The Script:
// Function to be applied to any element
jQuery.fn.preFade = function( speed, callback ) {
this.load(function(){
$(this).fadeIn(speed, callback);
});
};
// The .prefade class has display: none; applied to it in my CSS
$(document).ready(function(){
$('.prefade').preFade(1000);
});
The thing that stumps me the most is the fact that although the load event isn't triggered, the image is actually loaded. The reason I know this is because when I inspect the element, and change it to display: block; from display: none; the image appears.
I have an inkling there is perhaps something I am missing with the order in which events are called...

I was linked to a solution in the comments, this is how it fit into my code.
this.one('load', function(){
$(this).fadeIn(speed, callback);
}).each(function(){
if (this.complete) { $(this).load(); }
});
Changing from the simple $.load() function (which uses $.on('load')) to the $.one('load') function restricts the event to only firing once. if (this.complete) then checks whether it has been loaded before the event has even been binded to the element, and if it has, it will trigger the load event.
Link to solution

Use $(window).load event. This will only be trigered when all images are loaded
$(window).load(function(){
$('.prefade').preFade(1000);
});

Related

jQuery Event Listeners

Is there a way using jQuery to add event listeners much like the ones that are available in AS 3.0?
For example, if you load an image, (setting it's opacity to zero so that it doesn't appear on screen) does jQuery have something similar to an onComplete event listener that listens out for when load has completed? Once the load has successfully loaded then you could fire off another function to fade it's opacity back to 1 again.
I've seen a few plugins that have been written, but thought I'd ask a question to see if anyone has found an solution without the use of 3rd party plugins.
Thanks.
Something like this?
$(function(){
$("img").hide().load(function(){
$(this).fadeIn();
});
});
The first line is shorthand for $(document).ready(function(){
Then we simply select all the img elements, and hide them and add a load handler to them which fades them in.
Although, if cached the above could prove to be trouble. The below would solve this.
$(function(){
$("img").hide().each(function(){
if(!$(this).width()){ // image dimensions are unavailable if it's not loaded
$(this).load(function(){
$(this).fadeIn();
});
}else{ //if the image is loaded already
$(this).fadeIn();
}
});
});

jQuery .html function with .load

I am loading HTML content using jQuery's .html() function. Part of the HTML content I am trying to load are images, which take some time to be loaded. What I do is on an onclick event,
$('div').on('click',function() {
$('html').fadeOut(1000)
.html(content)
.load(function() {
$('html').fadeIn(1000)
});
});
What I wanted to happen is that, when the DOM has finished loading, I want it to fadeIn. If it is still not finished, I want it to stay hidden hence, the fadeOut function before the html load.
Is this possible? That method doesn't seem to work for me.
First, if you are replacing the entire HTML element, you might as well just do a full request cycle. That's essentially what you're going to end up with and it will be easier to hook to the window load event using a full request than to handle this with AJAX. If you're not replacing the entire page, then you've got your selector wrong.
Second, if you are just loading the DIV, then you can try hiding the DIV, binding the load event to it, then loading it with content. See the caveats for the http://api.jquery.com/load-event/ method for more information.
$('div').on('click',function() {
var $this = $(this); // save reference for future use
$this.fadeOut(1000) // hide
.load(function() { // hook up handler
$this.fadeIn(1000)
})
.html(content); // load content
});

Check for mouseenter after page is loaded

One of my elements has a mouseenter event on it. The trouble is, I can't add the event until the dom is fully loaded, so I use something like:
document.observe('dom:loaded', function() {
${"my_element").observe("mouseenter", function() { ... }
});
Now, the user might be mousing over the element before the page is fully loaded, and so the event doesn't fire. They have to move their mouse to have it fire. How can I detect if I should fire the event after the page is fully loaded, so the user doesn't have to move their mouse?
the $(document).ready(function(){ and $(function(){ fire when the dom is ready, use on to attach an event handler function for one or more events to the selected elements:
$(function(){
${"my_element").on("mouseenter", function() { ... }
});
This doesn't directly answer your question, but livequery might help you. I think it attaches event handlers immediately, but it might wait until the DOM has been loaded, in which case it doesn't help you.
Depending on the effect you're applying, can you use a CSS rule to simulate it?
Something like
#my_element:hover { color: red }
Then in jQuery, in your mouseenter method, jQuery.Rule to remove the rule.

how can i invoke a function after page is done loading? (and only then..)

I'm having trouble with some jquery code.
in my HTML page I use ajax to get some info, and then I'm changing an HTML element
with $("#id").html(...).
The problem is, I also have a $(document).ready code which I wanna call only once
when the page is done loading, but after each change in the html with the $("#id").html(...)
the code is called once again.
How can I run the $(document).ready code only once?
Here is an example:
$(document).ready(function(){
// this code will run not only once...
}
function f(){
$("#id").html(...);
}
Try:
var run = false;
$(document).ready(function() {
if(!run) {
...
run = true;
}
});
...or...
$(window).load(function() {
...
});
The first one will make sure it is only run once; the 2nd one is run when the entire page is finished loading (useful if you need to resize things once images have finished loading).
From the comments on the .ready documentation:
Looks like .ready() fires not only when page initially has settled the
DOM, but apparently also after changes to the DOM. This is an issue if
your ready handler changes the DOM. That will result in ready() firing
more than once. It may result in an endless loop if each invocation
adds yet more to the DOM. Firefox and IE behave differently to this,
including different error messages, and leaving the page display in
different states. So, if ready() modifies the DOM, then it would be
wise to have a way to check whether ready has already been fired.
Replying to self: Well it appears that part of the problem is not that
the ready function fires again (though that is possible aparently),
but that changing the DOM causes the script that creates the ready
function to fire again, adding an additional ready function, etc etc.
This seems to happen if the javascript is embedded in the html at a
point beyond (or contained in) the part of the DOM that the ready
handler modifies. (Obviously would be better to put script that
creates a ready function in the document head, but in this case that's
not an option.) Problem fixed by checking a global flag variable to be
undefined before executing jQuery(document).ready(...).
If this might be your problem, you can adopt the same solution:
var onLoadFired = false;
$(document).ready(function() {
/* Ensure this function only runs once */
if (onLoadFired) {
return;
}
else {
onLoadFired = true;
}
/* Business logic */
// .. your code here ..
});
Or, better, move your handler into a separate script file that's included by a script tag in your page's head element.
Try this:
$(window).bind("load", function() {
...
});

Javascript/jQuery HasLoaded or equivalent?

I know in jquery it is possible to call the javascript/jquery onload()/load() functions on, for example an image (<img>).
However, if in jquery if i use .html(htmlString) to insert an image after the dom has loaded, how can i add a listener to handle the images onload event? Is there a property I can check to see various images and if they have loaded?
After appending your html, you can bind the load event to the contained images:
$("#foo").html(htmlString).find("img").one("load", function() {
...
}).each(function() {
// image has been cached, so load event won't fire unless we explicitly call it
if(this.complete) $(this).trigger("load");
});
Check the complete property of the image(s)

Categories