Roberto Adarve
Roberto Adarve

Reputation: 167

Is there a 'ready' event fired when a jQuery element is created on the fly?

I'm trying to implement something like a photo carousel in jQuery. This carousel could be filled with images using an array of image sources (I make an ajax request that returns a json with this data) and, once is filled, you can call a couple of methods, previous() and next() to move the carousel backward and forward respectively.

The thing is that this functionallity is already implemented and working, but I can't solve an issue on resizing process. For avoid that the images exceed the boundaries of the container, I have a method for creating and resizing the images, if needed.

this.getImageResized = function(imageSrc) {

    var image = $('<img />', {src : imageSrc});

    // Container ratio
    var ratio = this.itemMaxWidth / this.itemMaxHeight;

    // Target image ratio is WIDER than container ratio
    if((image[0].width / image[0].height) > ratio) {
        if(image[0].width > this.itemMaxWidth) {
            image.css('width', this.itemMaxWidth + 'px');
            image.css('height', 'auto');
        }
    // HIGHER
    } else {
        if(image[0].height > this.itemMaxHeight) {
            image.css('width', 'auto');
            image.css('height', this.itemMaxHeight + 'px');
        }
    }

    // Embeds image into a wrapper with item's width and height
    var wrapper = $('<span style="display : block; float : left; width : ' + this.itemMaxWidth + 'px; height : ' + this.itemMaxHeight + 'px"></span>');

    image.appendTo(wrapper);

    return wrapper;
};

Testing this function, I've found that sometimes, images are not resized as expected. I've used firebug console.log() to log the image[0].width just below jQuery element creation, finding out that sometimes the value is 0.

I'm not an expert on jQuery, but I suppose that when this happens (value is 0) is because the element is not ready.

How can I assure that the element is already loaded when I ask for its width and height values?

Is something like this possible?

var image = $('<img />', {src : imageSrc}).ready(function() {
    // But image[0].width it's not available here!
});

Thank you for your help!

Upvotes: 7

Views: 8939

Answers (3)

spender
spender

Reputation: 120498

As per the answer provided here, I knocked together a working demo:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
  <script type="text/javascript">
   //<![CDATA[
    $(window).load(function(){
     //window load already fired
     setTimeout(function(){ 
      var img=$('<img />'); 
      img.appendTo($("body"));
      img.load(function(){alert("img is "+$(this).width()+"px wide.")});
     },5000) //5 secs delay. definitely adding "dinamically" 
      img.attr("src","http://sstatic.net/so/img/sprites.png");
    });
   //]]>
  </script>
 </head>
 <body>

 </body>
</html>

Upvotes: 0

azatoth
azatoth

Reputation: 2379

There's no platform compatible ways to see if a DOM object is "ready", see https://developer.mozilla.org/en/DOM_Events for gecko specific events

Upvotes: 1

Nick Craver
Nick Craver

Reputation: 630569

You want to use the load event in this case, like this:

var image = $('<img />', {src : imageSrc}).one('load', function() {
  // use this.width, etc
}).each(function() {
  if(this.complete) $(this).load();
});

The last bit triggers the load event in case it didn't get triggered already...which doesn't happen in some browsers when loading the image from cache, using .one() to one fire it only once and .complete to check if it's loaded.

Upvotes: 4

Related Questions