Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Brent Cralley
18,541 PointsJQuery script almost works... Any thoughts?
So I'm half expecting this to be a little typo, but I'm convinced that I can stare at the code all day and i won't see it...
The code makes it so that when I hover over 3 images in thumbnail form(li in the HTML), it creates a div with a larger version of that image. The hover function works, but for some reason the first image is the only one to appear in the larger div, even when I hover over the other two.
Is there some form of a break I should add? I'm too new to know too much detail about JQuery(but I did learn everything on here! Yay Treehouse!)
HTML code:
<p>
This is the paragraph that the new div is inserted after. It works great!
</p>
<ul id="image_list">
<li id="image_hover">
<img class="lightboxthumb" src="Image1.jpg" alt=""/>
</li>
<li id="image_hover">
<img class="lightboxthumb" src="Image2.jpg" alt=""/>
</li>
<li id="image_hover">
<img class="lightboxthumb" src="Image3.jpg" alt=""/>
</li>
</ul>
JQuery code:
//variables for image source elements to keep functions cleaner
var picture1 = 'img[src="Image1.jpg"]';
var picture2 = 'img[src="Image2.jpg"]';
var picture3 = 'img[src="Image3.jpg"]';
//function for first image - the one that appears when all thumbnails are hovered over
$("#image_list li").mouseenter(function () {
if ($(picture1)) {
$('<div class="image_box"><img src="Image1.jpg"></div>').insertAfter("p");
}
//function for second image - when hovered over, it shows the first image in the larger div
else if ($(picture2)) {
$('<div class="image_box"><img src="Image2.jpg"></div>').insertAfter("p")
}
//functions for third image - same as second image
else if ($(picture3)) {
$('<div class="image_box"><img src="Image3.jpg"></div>').insertAfter("p")
}
//removes large image when the mouse leaves the thumbnail - works great! no issues here!
$("#image_list li").mouseleave(function () {
$('.image_box').remove();
});
});
I should also mention that this code worked great when I first wrote it, but it took up about 5X as much space as this code, so this is my attempt to condense it and make it more efficient.
While I'm at it, can anyone else think of a more efficient way to create this same effect? I'm all ears for any improvement suggestions. :-)
Please let me know if you need any more info! I've been working on this for hours, so I'm not sure if I posted everything you need.
Thanks guys! I look forward to hearing from you!
2 Answers
Matthew Greenberg
8,173 PointsJquery has a shorthand for the mouseenter, mouseleave code block in the .hover method.
You can read about the hover method here.
It would also be easier to get the "src" attribute of the img you are hovering on instead of testing the img src string in an if loop.
Here is how i did it. You only need this code for it to work. You might not need the document.ready function so omit it if you need to.
$(document).ready(function(){
$('#image_list li img').hover(function(){
var img_file = $(this).attr("src");
$('<div class="image_box"><img src="' + img_file + '"></div>').insertAfter("p");
}, function(){
$('.image_box').remove();
});
});
Matthew Greenberg
8,173 PointsThe hover method doesn't call both of the functions immediately. It calls the first function on hover in, and the second function on hover out.
$( selector ).hover( handlerIn, handlerOut )
Good Luck!
Brent Cralley
18,541 PointsYour code worked brilliantly! I just added a few tweaks(for example, I put my script tag at the bottom of the HTML form, so I removed the ".ready" method.
Is it the comma right before the function for removing the image that makes that function trigger on the second event(.mouseleave part of .hover)?
This is exactly what I meant by wanting to condense it somehow. I wish I could have written it myself, but now I have a reference to go off of. :-)
Thanks a lot!
Matthew Greenberg
8,173 PointsYou got it! The second function is the mouse out event. Its probably easier to see if you use actual functions and plug them instead of anonymous ones.
var selector = '#image_list li img';
function handlerIn() {
var img_file = $(this).attr("src");
$('<div class="image_box"><img src="' + img_file + '"></div>').insertAfter("p");
};
function handlerOut(){
$('.image_box').remove();
};
$(selector)hover(handlerIn, handlerOut);
This is exactly the same code.
Brent Cralley
18,541 PointsOh I missed the handelerIn() and handelerOut() tags. I've never seen anything called out like that before.
So if you don't call out the handelers, you can get the same effect by closing out the first function(with one of these "}"), and then the browser knows that the second function is to be executed on the next event trigger(in this case, the handelerOut)?
I'm pretty sure I understand. Thanks for showing me!
Matthew Greenberg
8,173 PointsYea, the way i originally wrote the code was using anonymous functions. Its shorter to write and keeps the global namespace free of unnecessary function declarations.
Brent Cralley
18,541 PointsBrent Cralley
18,541 PointsThanks for the response, Matthew!
The reason I didn't use the .hover method is because it triggered twice; once for mouseenter, once for mouseleave. So the image would appear, then disappear on mouseenter, and the same with mouseleave.
But, looking at your code, it looks like one function triggers when the mouse enters the image, and the second function triggers when it leaves? Is this how it works?
You syntax does teach me a lot of things, though: -the ".attr" method can be used to call out the source of the images. -variables CAN be used as data to send back to the HTML document(I struggled with this a lot)
I'll insert my values and give your code a spin in a little bit and let you know how it runs.
Thanks again!