Reputation: 23
Hello,
I am trying to add classes to each image depending to its proportions (landscape/portrait/square). This code works in JSfiddle but not on the website (locally or on server):
$(document).ready(function()
{
$('img').addClass('wide');
$.each($('img'), function()
{
var image = $(this);
if (image.height() > image.width()) {
image.removeClass('wide');
image.addClass('tall');
} else if (image.height == image.width()) {
image.removeClass('wide');
image.addClass('square');
}
});
});
Here is my JSfiddle: http://jsfiddle.net/LYxv6/ .
Upvotes: 2
Views: 1682
Reputation: 11149
I would do something like this:
(function ($) {
$.fn.proportions = function (options) {
options = $.extend(options, {
wideClass : 'wide',
tallClass : 'tall',
squareClass : 'square'
});
addProportions = function () {
img = $(this);
var ratio = img.width() / img.height();
if (ratio > 1) {
return img.addClass(options.wideClass);
}
if (ratio === 1) {
return img.addClass(options.squareClass);
}
return img.addClass(options.tallClass);
};
return this.each(function () {
if ($(this).width() !== undefined) {
addProportions.call(this);
} else {
$(this).on('load', addProportions);
}
});
};
}(jQuery));
jQuery(function ($) {
jQuery('img').proportions();
});
Putting it in a plugin makes it re-usable. And instead of using window.load as jsfiddle is doing, I've attached the function to each image's load event, so that the class is added immediately.
Upvotes: 0
Reputation: 339836
The reason your code works on jsfiddle is because the site has (by default) wrapped your code in an onload
handler. This handler is called once all the images have loaded, unlike $(document).ready()
which only waits until the DOM structure is complete.
The function to change the classes is trivial if you take advantage of the version of addClass
that takes a function parameter instead of a string:
$(window).on('load', function() {
$('img').addClass(function() {
if (this.height === this.width) {
return 'square';
} else if (this.height > this.width) {
return 'tall';
} else {
return 'wide';
}
});
});
In the callback this
is the <img>
element itself, and you can directly access its .width
and .height
properties without having to use jQuery.
This should be far more efficient than repeatedly calling jQuery functions inside a .each()
loop.
Upvotes: 5
Reputation: 7491
Changed to $('img').each and missing paranthesis at image.height() (this is a function)
$(window).load(function() {
$('img').addClass('wide');
$('img').each(function() {
var image = $(this);
if (image.height() > image.width()) {
image.removeClass('wide');
image.addClass('tall');
}
else if (image.height() == image.width()) {
image.removeClass('wide');
image.addClass('square');
}
});
});
Upvotes: 1
Reputation: 1514
On your server on local system, make an .html file.
Change it to document load, put in missing braces for one of the width parts - and make sure the .html file looks like the below:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title></title>
<script>
$(document).load(function() {
$('img').addClass('wide');
$.each($('img'), function() {
var image = $(this);
if (image.height() > image.width()) {
image.removeClass('wide');
image.addClass('tall');
}
else if (image.height() == image.width()) {
image.removeClass('wide');
image.addClass('square');
}
});
});
</script>
<style>
img{
height:250px;
}
.wide{
border:10px solid #aed;
}
.tall{
border:10px dashed #dea;
}
.square{
border:10px dotted #ade;
}
</style>
</head>
<body>
<img src="http://24.media.tumblr.com/tumblr_m9t0dwyu0P1qjfsubo1_500.jpg"/>
<img src="http://24.media.tumblr.com/tumblr_m9iqv8oQl01qcpwsso1_500.jpg "/>
<img src="http://25.media.tumblr.com/tumblr_m9n4kyf8aA1r1thfzo5_1280.jpg"/>
</body>
</html>
You may replace <style></style>
and <script></script>
with <link rel="stylesheet" type="text/css" href="yourstyle.css"/>
and <script type ="text/javascript" src="jquerywhatever.js"></script><script type ="text/javascript" src="YOURSCRIPT.js"></script>
Upvotes: 0
Reputation: 7315
Try to use variables in if
else if
statements:
var biggerVal = image.height() > image.width();
var equalVal = image.height() == image.width();
if ( biggerVal ) {
image.removeClass('wide');
image.addClass('tall');
} else if ( equalVal ) {
image.removeClass('wide');
image.addClass('square');
}
Same problem on this question: How to build simple sticky navigation with jQuery?
Upvotes: 0
Reputation: 117334
You should run this script on
$(window).load()
...otherwise(on ready) it may happen that the images are not loaded yet and the size is still unknown when you access them.
You also forgot some parentheses here:
else if (image.height == image.width()) {
should be
else if (image.height() == image.width()) {
Upvotes: 1