2

I wanted to know how to use JQuery to create a function that will run on each time an image has been finished loading. I want that function to be called EACH TIME, not only once. So if, for example, I have "image1.jpg" and it was loaded on page start, the function will be called. Then, if I change the image and it was loaded again after I changed it using Javascript, I want that 'loaded' function to fire again. I tried Jquery Load() function, but it only run once, not the second time after the image has been replaced with another one.

I want also that the even will happen even if the image has been cached too. That means that every time I change thew 'src' attribute of the image, I want that a specific function to fire up - again, even if the image is already been cached.

Example:

$("#myimageselector").attr("src", "http://domain.com/the_new_image.jpg");

I want that when this happens, even if the image is already cached the function will fire. I think that it's possible to know if the images has been cached, kind of. I just need to have an .load() function that will run once (of course), and if it hasn't been executed, it means that the image has been cached. At least for my specific usage.

Thought: maybe we should bind an event that checked a change in the DOM for a specific element change. So maybe if the image has been finished loading, a specific DOM element is changed, so we can check the before and after values.

Thanks.

Liron Harel
  • 10,819
  • 26
  • 118
  • 217

4 Answers4

5

The closest I get to your desired solution, to also deal with cached images.
I've created a jQuery plugin:

(function($){
    var dummy_img = "dummy1x1.png",
        dummy_width = 1,
        dummy_height = 1;

    $("<img>").attr("src", dummy_img); //Preload image

    $.fn.setSrc = function(src, func, args){
        var $img = this;
        if(/img/i.test(this.get(0).tagName)) return; //Cancel at non-IMG elements
        if(!(args instanceof Array)) args = [];
        var poller = window.setInterval(function(){
            if($img.height() != dummy_height || $img.width() != dummy_width){
                loaded();
            }
        }, 200);
        $img.attr("src", dummy_img);
        $img.bind("load", loaded);
        $img.bind("error", clearPoller);
        function loaded(){
            clearPoller();
            //If a callback function exists, execute it
            if(typeof func == "function") func.apply($img,args);

            func = null;//Prevent unwanted executions
        }
        function clearPoller(){
            window.clearInterval(poller);
        }
    }
})(jQuery);

Usage:

$("#myImg").setSrc("image.png", function(){
    alert(this.attr("src") + " has loaded!");
});

The concept behind this:

  1. Change width and height to 1 (using the preloaded dummy image)
  2. Bind load and error event handlers
  3. Run a poller which checks for the width and height of the image.
  4. When the image has finished/failed loading, the load or error event will be triggered. Upon triggering, the poller is cleared, and the passed function is executed.
  5. When none of these events are fired, the poller is still able to detect a change in image size. When the cached image is loaded, the width/height of the element updates, which is detected by the poller. In this case, the poller clears the interval, and executes the passed function.
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • 1
    I don't believe you can use `live` with the `load` event since it doesn't seem to bubble. At least [in this example](http://jsfiddle.net/s5zjj/) it doesn't fire. Also, you really don't need to place `.live()` code in `$(document).ready(...)`. If you're going to use `.live()`, it is better placed outside so the handler will fire if an event occurs before the DOM is ready. – user113716 Oct 10 '11 at 20:54
  • doesn't fire. I also want it to fire when the image has already been cached – Liron Harel Oct 10 '11 at 21:16
  • Unfortunately, there's no way to detect when a cached image is reloaded. If the images are small, and the load event is extremely important to you, you can disable caching by appending a random query string to the image, eg: `img.src = "img.png?"+(new Date).getTime()`. – Rob W Oct 10 '11 at 21:18
  • cache is very important, because I pay for the bandwidth :) – Liron Harel Oct 10 '11 at 21:19
  • *"there's no way to detect when a cached image is reloaded"* You can ask an image if it is complete, and if so, manually invoke the bound load handler. – user113716 Oct 10 '11 at 21:21
  • @Idan, I've updated my answer, which also deals with cached images. – Rob W Oct 10 '11 at 21:48
  • Images have a `.complete` property that will tell you if the image has already loaded. – user113716 Oct 10 '11 at 23:49
  • if(/img/i.test(this.get(0).tagName)) will return always true, suppose to be 'not', am I right? – Liron Harel Oct 11 '11 at 00:05
1

you can use the onLoad function for the Img tag

$(".img").load(function (){
    // do something
});
Royi Namir
  • 144,742
  • 138
  • 468
  • 792
0
$('img').live('load', function ()
{
    alert("image loaded: "+this.src);
});

Use jquery live method to track load.

Senad Meškin
  • 13,597
  • 4
  • 37
  • 55
0

This will run whether image is cached or not:

$(document).ready(function() {
    var imgLoadFunc = function() {
        //code to run
    };

    $("img").each( function() {
        if(this.complete) {
            imgLoadFunc.call(this);
        } else {
            $(this).load( function() {
                imgLoadFunc.call(this);
            });
        }
    });
});

Strictly speaking, you don't need to use call(), but this will allow you to use the image element in question in a more jquery-ish way. Inside imgLoadFunc:

var img = $(this);
uɥƃnɐʌuop
  • 14,022
  • 5
  • 58
  • 61
  • It doesn't fire the imgLoadFunc when image is changed using the $("#img").attr('src', 'http://domain.com/the_new_image.jpg') call. It fires once because the image is cached. – Liron Harel Oct 10 '11 at 21:44
  • Ah, right. Yeah, that only covers the page load. Sorry, I read through too fast. But I did a quick test, and dynamically updating the image this way called the load callback: `$("#theImg").attr("src","theUrl").load(function() { loadFunc.call(this); });` both cached and otherwise – uɥƃnɐʌuop Oct 10 '11 at 22:08