Reputation: 41
I am quite new to Jquery and i have the following problem.
I wrote a function to resize images while keeping the aspect ratio. I have some more "if" than needed in this version just to be more readable. The html structure is something like that.
<div class="post">
<div class="date"></div>
<div class="thumbnail">
<img class="img-thumb" />
</div>
<div class="post-body">
<p>...</p>
<img />
<p>...</p>
</div>
</div>
For the resizing (i also center the image by adding some padding. I think i don't have a mistake to that part of the code.)
$(window).load(function() {
var parentWidth = 250;//max width. In the real script i get the parent width inside the each but for the example a static value is ok
var parentHeight = 196;//max height
$('.img-thumb').each(function () {
var img=$(this);
var width = img.width(); //image width
var height = img.height(); //image height
var aspect = width/height;
var wide = width/parentWidth;
var tall = height/parentHeight;
if(width > parentWidth) {
if (wide > tall) {
width = parseInt(parentWidth,10);
height = parseInt(parentHeight/aspect,10);
}
}
if(height > parentHeight) {
if (tall > wide) {
height = parseInt(parentHeight,10);
width = parseInt(parentWidth*aspect,10);
}
}
margin_top = parseInt((parentHeight - height) / 2,10);
margin_left = parseInt((parentWidth - width ) / 2,10);
img.css({'margin-top' :margin_top + 'px',
'margin-left':margin_left + 'px',
'height' :height + 'px',
'width' :width + 'px'
});
});
});
And here is my problem. I don't understand exactly how the load works. I mean. This will work but only when all the images are loaded. But it has two problems. The first is that it has to wait for all to load and the second is that the user will see the resizing so i first have to hide the images and show them with show(). I can do it in css but this way when javascript is disabled they will still be hidden so i prefer to do it in jquery.
I could run a second .each before that one and hide them all but i guess going to the dom for a second time running an each for the same thing is not the best solution. So how the load works exactly?
If i do this for example:
$('.img-thumb').each(function () {
var parentWidth = 250;//max width. In the real script i get the parent width inside the each but for the example a static value is ok
var parentHeight = 196;//max height
var img=$(this);
img.hide();
img.load(function() {
var width = img.width(); //image width
var height = img.height(); //image height
var aspect = width/height;
var wide = width/parentWidth;
var tall = height/parentHeight;
if(width > parentWidth) {
if (wide > tall) {
width = parseInt(parentWidth,10);
height = parseInt(parentHeight/aspect,10);
}
}
if(height > parentHeight) {
if (tall > wide) {
height = parseInt(parentHeight,10);
width = parseInt(parentWidth*aspect,10);
}
}
margin_top = parseInt((parentHeight - height) / 2,10);
margin_left = parseInt((parentWidth - width ) / 2,10);
img.css({'margin-top' :margin_top + 'px',
'margin-left':margin_left + 'px',
'height' :height + 'px',
'width' :width + 'px'
}).show();
});
});
It doesn't work. I mean i can still see the resizing. I guess the reason is that the second part of the each loop will not executed before the first image is loaded. So how can i tell jquery to execute the outdise of the load code? Do i need two .each?
Upvotes: 2
Views: 2484
Reputation: 2695
And here is my problem. I don't understand exactly how the load works. I mean. This will work but only when all the images are loaded
jQuery starts working when the DOM is fully loaded, and that is why every action will be visible to the user. When you call $(document).ready();
, you are actually telling jQuery that it should wait until the page is finished loading before it does the required action.
Now, to answer your question:
If I understand correctly, you have images that are bigger than the size you desire to display on the page and you are using jQuery to give them the required dimensions?
You could use CSS
to hide the images as the page is being rendered. When it finishes to load, you could then use jQuery to change the size, and then make the images visible again. Refer to this example: http://jsfiddle.net/CYfma/
Why would you want to do this? The best thing to do here (provided you know the targeted thumbnail size in advance), is to store the images already resized. This is the concept that Facebook and many other websites use to save bandwidth. Rendering large images and resize them on the client side does not make them smaller in weight. This has a large impact on the speed at which your page loads.
If you know the target size in advance, you could also just use the width and height properties of the image in CSS or HTML to make them the desired size.
EDIT
In response to your concern about disabled javascript, this is my suggestion:
Instead of using
CSS
, you could usejavascript
(not jquery yet) to hide the image. This means that with javascript enabled, the image will be hidden until jQuery kicks in. According to my understanding and observations, a line such asdocument.getElementById("image").style.display="none";
should execute before the code blocks inside$(document).ready();
. I have tried that solution, you can check it out here: http://jsfiddle.net/CYfma/1/
I hope I understood your question properly, if not, I sincerely apologise :-)
Hope it helps
Upvotes: 0
Reputation: 116
Your problem is that you bind load event when you actually load all the elements by "$(window).load(...)"
You want to bind load event to your images when you download your HTML dom, but you want your images to be resized and show them after they are loaded. Thus,
Instead of "$(window).load(...)" use "$(document).ready(...)", then give $('.img-thumb') the load event as "$('.img-thumb').load(..)"; You don't need to use each, because all the images have "img-thumb" class will have that load event which you do your resizing operations in your case.
Upvotes: 1