Reputation: 2288
I've got quite the problem with jQuery and a custom photo gallery I am building. I've searched high and low and tried endlessly different solutions but nothing is working perfectly. So let me present the information:
This photo gallery has thumbnails on the left side and a big image in the center. Every thumbnail can be clicked which calls a function passing in its' ID. What I want it to do is, AJAX POST to server to get image comment and image name. Fadeout the current big picture div, switch the src in the img tag, get the new image's width, set the width of an overlaying comment div, fadeIn the big picture div.
The problem is that I can't get the width of the new image after it has loaded (even using the a form of .load() to wait for the image to finish loading). Now I can get it to work when I fadeIn the new image and then get the width but that isn't what I need. I need to get the width and set the div's width before I fadeIn.
Any ideas or corrections would be great, hopefully I have provided enough information.
Here is the code I am wrestling with:
function thumbClick(val) {
$.post('ajax.php', {
photo_in: val
}, function (data) {
$('div#picture').fadeOut('slow', function () {
//$('img#big-picture').load(function(){
$('img#big-picture').one('load', function () {
//alert($('img#big-picture').width());
//will alert 0
$('div#picture').fadeIn('slow', function () {
$('div#comment-box').width($('img#big-picture').width());
//set comment to what I want
$('p#comment').html("");
//alert($('img#big-picture').width());
//will alert new image width after FadeIN
$('p#comment').html(data.comment);
});
}); //end of one(load)
$('img#big-picture').attr("src", data.newImage);
}); //end of fadeout
}, "json"); //end of post
}
Upvotes: 0
Views: 3544
Reputation: 359816
The width is zero because hidden elements (elements with display: none
have, by definition, zero height and width). After fadeOut()
, jQuery hides the element(s). A few different solutions:
.fadeTo()
, not .fadeOut()
:$('#picture').fadeTo('slow', 0, function () {
var $pic = $(this);
$('#big-picture').one('load', function () {
var $bigPic = $(this);
$pic.fadeIn('slow', function () {
$('#comment-box').width($bigPic.width());
$('#comment').html(data.comment);
});
}).attr('src', data.newImage);
});
<img>
element:$('#picture').fadeOut('slow', function () {
var $pic = $(this);
$('#big-picture').one('load', function () {
var img = new Image(),
width;
img.src = this.src;
width = img.width;
$pic.fadeIn('slow', function () {
$('#comment-box').width(width);
$('#comment').html(data.comment);
});
}).attr('src', data.newImage);
});
CSS
.off-left {
position: absolute;
left: -99999px;
}
JavaScript
$('#picture').fadeOut('slow', function () {
var $pic = $(this);
$('#big-picture').one('load', function () {
var $this = $(this),
width = $this.addClass('off-left').show().width();
$this.removeClass('off-left').hide();
$('#picture').fadeIn('slow', function () {
$('#comment-box').width(width);
$('#comment').html(data.comment);
});
}).attr('src', data.newImage);
});
Upvotes: 1
Reputation: 10087
You should be able to set the CSS property visibility
to hidden
and then get the width, as visibility
doesn't take it out of the document flow (like display: none
), but simply makes it invisible. Just make sure you set the visibility
property back to visible
when you fade in.
Upvotes: 0
Reputation: 8942
I've encountered this before; what seems to be the easiest solution is to quickly show the image, grab it's width, and hide it again. This operation occurs so quickly users will never notice. In your case, i believe the code would be:
$("#big-picture").show();
alert($('#big-picture').width()); //this should be the real width, now
$("#big-picture").hide();
Upvotes: 1