views:

32

answers:

3

I have an image that is wrapped inside a couple of DIV elements

<div id="wrapper">
...
<img src="myphoto.png" height="400px" width="500px>
</div>

I use jQuery, to access the height or width I either use

jQuery(img).attr('height');

or

jQuery(img)[0].height;

Unluckily, when the wrapping DIV 'display' property change, these values are set to 0 for example, if I do

$('#wrapper').hide()
then
jQuery(img)[0].height = 0;

The same for the attributes.

Any idea how to fix this, showing the DIV, getting the values and hidding it again does solve the problem, however I can't guess the number of wrapping DIVs as it can (and their behaviors change).

Thanks

Edit: Thanks for all answers. However, I forget to mention that I don't control DIV hiding and style. My script plays with Images and is made to integrate in any page, so the user is the one who do hide/Show/change the values.

+5  A: 

Use .css() to get the stored value instead, like this:

jQuery('img').css('height');

I know it sounds a bit strange, but before you dismiss it, try it :)

Nick Craver
That will only work when you have explicitly set the width in either CSS or using properties. (indeed, the OP's image has these specified, I noticed to, just for other cases when the image does not)
Pim Jager
Thanks you saved my life :)
Omar Abid
+1 Very simple and nice solution.
Gert G
@Pim: in those situations, you can get the computed style of an element using *window.getComputedStyle()* (W3C) or *element.currentStyle* (IE6-8). If the element is hidden, you can show it, get the dimensions and hide it again before the display is updated.
Andy E
A: 

The same as my answer here:

http://stackoverflow.com/questions/3530127/convert-css-width-string-to-regular-number/3530169#3530169

Instead of hiding it with .hide() (display: none) you could hide it with .css('visible', 'hidden') then .width()/.height() will work.

If you don't want to change your .hide()´s then you could apply visible: hidden and thereafter .show() and then measure the height. After you have measured it, reverse that. Objects still affects the page layout when they are hidden by visible: hidden - beware of that.

To avoid tags which mess with the layout, you could set the position to absolute, move it to the body tag and then measure.

lasseespeholt
This has a different effect though, as the `<div>` would still occupy space in the page, often this isn't an option :)
Nick Craver
Yup, I have added some more. This will also work without `height` set explicit.
lasseespeholt
@lasseespeholt - It's actually a *good* practice to set the height :) This saves the browser time in figuring out the layout, and not re-flowing once the image is loaded :)
Nick Craver
Agreed, in this case your solution is simply the way to go. But I also though about tags in general. +1 for your solution.
lasseespeholt
A: 

I usually do this, when you cache the width and height before the hiding you can still use them. Something like this:

var dimensions = {width: $(img).width(), height: $(img).height()};
$(img).hide();

Or when you can't do this because the hiding and the need for the value are spread out you could save the height and width in the data object

$(img).data('dimensions', {width: $(img).width(), height: $(img).height()});

Then you can acces them like this:

 $(img).data('dimensions').width;

You could even make sure that all images on the page have these data properties using the following code:

$(document).ready(function(){
    $('img').each(function(){ //embedded images
        $this = $(this);
        $this.data('dimensions', {width: $this.width(), height: $this.height()});
    });
    $('img').live('load', function(){ //inserted images
        $this = $(this);
        $this.data('dimensions', {width: $this.width(), height: $this.height()});
    });
});
Pim Jager