PDA

View Full Version : Call href from thumbnail into image



MathewHood
06-14-2011, 05:46 AM
Hey everyone,

I have been working on this piece of script for a fair bit of today and I am stuck. Basically what I want the script to do, is have three thumbnails and one large image. When you roll over the thumbnails it changes the large image. Clicking on the thumbnail will go to a various url, eg. www.google.com.

All of this works, what I now want to do, is grab the href from the thumbnail, and place it on the large image so that you can click either the thumbnail or the large image to view the page.

If anyone is able to help me with this I would greatly appreciate it!

Here is my code so far, and a working example can be found at

http://testing.lifestyletrader.com/slider

JS File

$(document).ready(function(){

$('#thumbs ul li a').hover(
function() {
var currentBigImage = $('#bigpic img').attr('src');
var newBigImage = $(this).attr('title');
var currentThumbSrc = $(this).attr('rel');
var currentHref = $(this).attr('href');
switchImage(newBigImage, currentBigImage, currentThumbSrc, currentHref);
},
function() {}
);



function switchImage(imageHref, currentBigImage, currentThumbSrc, currentHref) {

var theBigImage = $('#bigpic img');

if (imageHref != currentBigImage) {

theBigImage.fadeOut(0 , function(){
theBigImage.attr('src', imageHref).fadeIn(0);

var newImageDesc = $("#thumbs ul li a img[src='"+currentThumbSrc+"']").attr('alt');
$('p#desc').empty().html(newImageDesc);

var newBigHref = $("#thumbs ul li a img[src='"+currentHref+"']").attr('href');

});


}

}

});


HTML file

<!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>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>Image slider</title>

<link href="css/gallery-styles.css" rel="stylesheet" type="text/css" media="all" />
<link href="css/sexy-button.css" rel="stylesheet" type="text/css" media="all" />




<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script type="text/javascript" src="int.js"></script>


</head>

<body>

<div id="wrap">

<div id="left">

<div id="bigpic" class="b">
<a href="http://www.google.com"><img src="images/big/largeImageOne.jpg" alt="iPod Shuffle 16GB Zoom View" /> </a>
</div>

<div id="thumbs">
<ul>
<li><a href="http://www.google.com" rel="images/big/financialInfoOver.jpg" title="images/big/largeImageOne.jpg">
<img src="images/small/financialInfoOver.jpg" alt="iPod Shuffle Front View In Blue!" />
</a>
</li>

<li>
<a href="http://www.yahoo.com" rel="images/big/largeImageTwo.jpg" title="images/big/largeImageTwo.jpg">
<img src="images/small/institutionalServicesStatic.jpg" alt="iPod Shuffle Dual View Grey!" />
</a>
</li
>
<li>
<a href="http://www.amazon.com" rel="images/big/largeImageThree.jpg" title="images/big/largeImageThree.jpg">
<img src="images/small/investorTechnologyStatic.jpg" alt="iPod Shuffle 16GB Zoom View" />
</a>
</li>
</ul>

</div>

</div>

<div class="clear"></div>

</div>

</body>

</html>

jscheuer1
06-14-2011, 06:43 AM
Something like (untested):


. . .
if (imageHref != currentBigImage) {
$('#bigpic a').attr('href', currentHref);
theBigImage.fadeOut(0 , function(){
theBigImage.attr('src', imageHref).fadeIn(0);
. . .

MathewHood
06-14-2011, 06:52 AM
You sir, are a genius!

This works 2/3rds correctly haha.

For the second and third thumbnail, it grabs the HREF and places it in the bigImage. However the first thumbnail is going unaffected which is bizarre.

I swear on my life that I had tried exactly what you typed though, however I had it placed under the fade, not sure if that would have made a difference.

Now I need to work out why the first thumbnail isn't updating its HREF :/

jscheuer1
06-14-2011, 09:52 AM
In your live demo currently you've left out the highlighted line:


$(document).ready(function(){

$('#thumbs ul li a').hover(
function() {
var currentBigImage = $('#bigpic img').attr('src');
var newBigImage = $(this).attr('title');
var currentThumbSrc = $(this).attr('rel');
var currentHref = $(this).attr('href');
switchImage(newBigImage, currentBigImage, currentThumbSrc, currentHref);
},
function() {}
);



function switchImage(imageHref, currentBigImage, currentThumbSrc, currentHref) {

var theBigImage = $('#bigpic img');

if (imageHref != currentBigImage) {
$('#bigpic a').attr('href', currentHref);
theBigImage.fadeOut(0 , function(){
theBigImage.attr('src', imageHref).fadeIn(0);

var newImageDesc = $("#thumbs ul li a img[src='"+currentThumbSrc+"']").attr('alt');
$('p#desc').empty().html(newImageDesc);

});


}

}

});

As a result the big image never changes and when hovering the trigger for the first one:


if (imageHref != currentBigImage) {

is never true. Reinstating the missing line should do the trick.

By the way, in an unrelated matter:


$('#thumbs ul li a').mouseenter(
function() {
var currentBigImage = $('#bigpic img').attr('src');
var newBigImage = $(this).attr('title');
var currentThumbSrc = $(this).attr('rel');
var currentHref = $(this).attr('href');
switchImage(newBigImage, currentBigImage, currentThumbSrc, currentHref);
}
);

is the same as:


$('#thumbs ul li a').hover(
function() {
var currentBigImage = $('#bigpic img').attr('src');
var newBigImage = $(this).attr('title');
var currentThumbSrc = $(this).attr('rel');
var currentHref = $(this).attr('href');
switchImage(newBigImage, currentBigImage, currentThumbSrc, currentHref);
},
function() {}
);

without the need of the empty function.

MathewHood
06-14-2011, 10:57 PM
Hey John,

Thankyou again for this, you are awesome! I just may have to donate to some links in your signature to show my true thanks!

I have one slight issue now, the images take a LONG time to load the rollover state. Once they have loaded they are fine, but the initial load is slow!

I have a feeling it has something to do with this line of code:


theBigImage.fadeOut(0 , function(){
theBigImage.attr('src', imageHref).fadeIn(0);

Is there any reason that this would cause the images to load slower? I will paste the new, completed source below.


$(document).ready(function(){

$('#thumbs ul li a').hover(
function() {
var currentBigImage = $('#bigpic img').attr('src');
var newBigImage = $(this).attr('title');
var currentThumbSrc = $(this).attr('rel');
var currentHref = $(this).attr('href');
switchImage(newBigImage, currentBigImage, currentThumbSrc, currentHref);
},
function() {}
);



function switchImage(imageHref, currentBigImage, currentThumbSrc, currentHref) {

var theBigImage = $('#bigpic img');

if (imageHref != currentBigImage) {
$('#bigpic a').attr('href', currentHref);
theBigImage.fadeOut(0 , function(){
theBigImage.attr('src', imageHref).fadeIn(0);

var newImageDesc = $("#thumbs ul li a img[src='"+currentThumbSrc+"']").attr('alt');
$('p#desc').empty().html(newImageDesc);

});


}

}

});



<!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>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>Image slider</title>

<link href="css/gallery-styles.css" rel="stylesheet" type="text/css" media="all" />
<link href="css/sexy-button.css" rel="stylesheet" type="text/css" media="all" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script type="text/javascript" src="int.js"></script>

</head>

<body>

<div id="wrap">

<div id="left">

<div id="bigpic" class="b">
<a href="http://www.google.com"><img src="images/big/largeImageOne.jpg" alt="iPod Shuffle 16GB Zoom View" /> </a>
</div>

<div id="thumbs">
<ul>
<li><a href="http://www.google.com" rel="images/big/financialInfoOver.jpg" title="images/big/largeImageOne.jpg">
<img src="images/small/financialInfoOver.jpg" alt="iPod Shuffle Front View In Blue!" />
</a>
</li>

<li>
<a href="http://www.yahoo.com" rel="images/big/largeImageTwo.jpg" title="images/big/largeImageTwo.jpg">
<img src="images/small/institutionalServicesStatic.jpg" alt="iPod Shuffle Dual View Grey!" />
</a>
</li
>
<li>
<a href="http://www.amazon.com" rel="images/big/largeImageThree.jpg" title="images/big/largeImageThree.jpg">
<img src="images/small/investorTechnologyStatic.jpg" alt="iPod Shuffle 16GB Zoom View" />
</a>
</li>
</ul>

</div>

</div>

<div class="clear"></div>

</div>

</body>

</html>

jscheuer1
06-15-2011, 03:34 AM
No reason at all. That's a little, if you will, Web Images 101. It's the time it takes the image to load. The images are a bit overweight byte wise. They would take less time at - say about 25k each instead of the current about 150k each. This could be done with image optimization with little loss in apparent quality. Here's the first one optimized (click to see full size):

3938

It comes in at 23k.

But that's only half the battle. No matter how small an image is, if it's being presented to the browser for the first time (hasn't been cached yet), it takes however long that it takes to download. Even with a simple rollover of a menu image (typically about 3k), this lag can be noticeable, especially on slower connections.

The way around that is to preload any images that aren't going to be loaded as the page loads. But preloading takes just as long as loading, so it's still important to first optimize each image. Since largeImageOne is loaded as the page loads, we only need to worry about the other two. Here's one way to preload them:


$.each(['images/big/largeImageTwo.jpg', 'images/big/largeImageThree.jpg'], function(i, im){
$(new Image()).attr('src', im);
});

This type of preloading (where we know the paths and filenames) can and generally should be done as soon as possible in the order of script execution and page load. Like here:


$.each(['images/big/largeImageTwo.jpg', 'images/big/largeImageThree.jpg'], function(i, im){
$(new Image()).attr('src', im);
});

$(document).ready(function(){

$('#thumbs ul li a').hover(
function() {
var currentBigImage = $('#bigpic img').attr('src');
var newBigImage = $(this).attr('title');
var curre . . .

MathewHood
06-15-2011, 10:50 PM
Hey John,

I had actually been looking into preloaders as I thought that may be the issue! That has dramatically increased my load time thanks!!

One last question I have though, is it possible to create a rollover state for the thumbnails? Since it is grabbing the image source from the 'rel', I have been finding it hard to write a newThumb that replaces the current rel with a +'_over'.

In saying that, would I need to revert back to using the empty function method before, but using the empty function to set the thumbnail back to its normal value without the _over?

MathewHood
06-15-2011, 11:22 PM
Just an update post, this is some code I have been working on this morning. I also made a mistake in my previous post, the thumbnail image is pulled from the src, not the rel.

Issues I think I am going to run into is because the src of the thumbnail is a .jpg file, adding the _over to it will make the source thumnailName.jpg_over

Here is what I had worked on so far, hopefully someone can help me out!!


$(document).ready(function(){

$('#thumbs ul li a').mouseenter(
function() {
var currentBigImage = $('#bigpic img').attr('src');
var newBigImage = $(this).attr('title');
var currentThumbSrc = $(this).attr('rel');
var currentHref = $(this).attr('href');
var currentThumb = $(this).attr('src');
switchImage(newBigImage, currentBigImage, currentThumbSrc, currentHref, currentThumb);
}
);
$('thumbs ul li a').mouseleave(
function() {
var currentThumb = $(this).attr('src', newThumb.replace(/'_over'/, ''));
}
);

function switchImage(imageHref, currentBigImage, currentThumbSrc, currentHref, currentThumb) {

var theBigImage = $('#bigpic img');

if (imageHref != currentBigImage) {
$('#bigpic a').attr('href', currentHref);

$('#thumbs ul li a').attr('src', currentThumb + '_over');

theBigImage.fadeOut(0 , function(){
theBigImage.attr('src', imageHref).fadeIn(0);

var newImageDesc = $("#thumbs ul li a img[src='"+currentThumbSrc+"']").attr('alt');
$('p#desc').empty().html(newImageDesc);

});


}

}

});

jscheuer1
06-16-2011, 01:03 AM
The code in your last post is a bit confused. Were you have:


$('#thumbs ul li a').mouseenter(
function() {
var currentBigImage = $('#bigpic img').attr('src');
var newBigImage = $(this).attr('title');
var currentThumbSrc = $(this).attr('rel');
var currentHref = $(this).attr('href');
var currentThumb = $(this).attr('src');
switchImage(newBigImage, currentBigImage, currentThumbSrc, currentHref, currentThumb);
}
);

The keyword this in the second highlighted line refers to the a tag which has no src attribute.

Later when you set it:


$('#thumbs ul li a').attr('src', currentThumb + '_over');

regardless of the fact that it won't be a valid filename, setting the a tag's src attribute will accomplish nothing toward your objective here.

It would probably be easier to break it out. Have separate events for the thumbnail image and the link. They can be combined by walking the DOM a little, but let's try to keep it as simple as possible for now.

Try this - remove all mention of the thumbnail image from the current code and make a separate hover event:


$('#thumbs ul li a img').hover(function(){
this.src = this.getAttribute('data-over');
}, function(){
this.src = this.getAttribute('data-out');
});

Now your thumbnail image tags can look like so for example:


<img src="images/small/institutionalServicesStatic.jpg"
data-over="images/small/institutionalServicesOver.jpg"
data-out="images/small/institutionalServicesStatic.jpg"
alt="iPod Shuffle Dual View Grey!" />

MathewHood
06-16-2011, 11:04 PM
Hrm, that works for the rollover states, but in the same time broke the image swap of the large image. I thought it was just because in the <img> tag for the new rollovers it didn't contain the title attribute.

Here is what the code looks like now with the thumbnail pieces omitted.


<script type="text/javascript">
$.each(['http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/big/largeImageTwo.jpg', 'http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/big/largeImageThree.jpg', 'http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/financialInfoStatic.jpg', 'http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/financialInfoOver.jpg', 'http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/institutionalServicesStatic.jpg', 'http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/institutionalServicesOver.jpg', 'http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/investorTechnologyStatic.jpg', 'http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/investorTechnologyOver.jpg'], function(i, im){
$(new Image()).attr('src', im);
});

$(document).ready(function(){

$('#thumbs ul li a').mouseenter(
function() {
var currentBigImage = $('#bigpic img').attr('src');
var newBigImage = $(this).attr('title');
var currentThumbSrc = $(this).attr('rel');
var currentHref = $(this).attr('href');
switchImage(newBigImage, currentBigImage, currentThumbSrc, currentHref);
}
);

$('#thumbs ul li a img').hover(function(){
this.src = this.getAttribute('data-over');
}, function(){
this.src = this.getAttribute('data-out');
});

function switchImage(imageHref, currentBigImage, currentThumbSrc, currentHref) {

var theBigImage = $('#bigpic img');

if (imageHref != currentBigImage) {
$('#bigpic a').attr('href', currentHref);

theBigImage.fadeOut(0 , function(){
theBigImage.attr('src', imageHref).fadeIn(0);

var newImageDesc = $("#thumbs ul li a img[src='"+currentThumbSrc+"']").attr('alt');
$('p#desc').empty().html(newImageDesc);

});


}

}

});


<div id="sliderWrapper">
<div id="leftWrapper">
<div id="leftContent">
<div id="bigpic">
<a href="http://www.google.com"><img src="http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/big/largeImageOne.jpg" alt="." /></a>
</div>
</div>
</div>
<div id="rightWrapper">
<div id="thumbs">
<ul>
<li><a href="http://www.google.com"><img src="http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/financialInfoStatic.jpg" data-over="http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/financialInfoOver.jpg" data-out="http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/financialInfoStatic.jpg" alt="" /></a></li>
<li><a href="http://www.yahoo.com"><img src="http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/institutionalServicesStatic.jpg" data-over="http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/institutionalServicesOver.jpg" data-out="http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/institutionalServicesStatic.jpg" alt="" /></a></li>
<li><a href="http://www.amazon.com"><img src="http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/investorTechnologyStatic.jpg" data-over="http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/investorTechnologyOver.jpg" data-out="http://testing.lifestyletrader.com/gfnn/wp-content/themes/GFNN/images/small/investorTechnologyStatic.jpg" alt="" /></a></li>
</ul>
</div>
</div>
</div>

For a working example you can see http://testing.lifestyletrader.com/gfnn/

I am confused as to why it won't show them now, I may have a play around with the title attribute again because I have a gut feeling it is that.

MathewHood
06-16-2011, 11:13 PM
Just as a second thought also, would it be possible to swap the title attribute for the large image to the alt?

When you hover over the thumbnails it shows the title which is the URL to the big image and it looks kind of bad, plus I don't really need the alt tags in there except for validity.

jscheuer1
06-17-2011, 03:42 AM
If you use an HTML 5 DOCTYPE you may use the data hyphen attributes for just about any string data you wish and it will be valid. Incidentally, the use of rev and rel for things like this is technically invalid. Those are reserved for link types. Technically alt should be empty or descriptive of the image if missing. In HTML 5 it supposedly may now be omitted if there's nothing to put in there. That standard is still in development though.

Getting back to your code, it really could use some simplification. And if you're concerned with validity, either set the image information as variables or use data hyphen attributes in HTML 5.

When I get more time I will have another look at it. However, I'd be inclined to just go back to what worked and add in the new code from there taking care not to break any of it. It can all coexist. Once that's done, or before you start even, get rid of anything that's not needed.

MathewHood
06-17-2011, 04:43 AM
Hey John,

Thanks for the advice, it worked perfectly. I now have it all working as intended! (Although I am yet to browser test haha!)

I am glad that you didn't have enough time to take a look at it more closely, I think I was starting to rely on your code snippets then actually doing the work myself!

Thank you once again for all your help with this, you truly are a JS genius, and a life saver!

-Mathew Hood