Swolschblauw Swolschblauw - 28 days ago 16
Javascript Question

Mouse / Hover over image change parent image src

I have the following problem, lets say this is my html

<ul classname='products'>
<li classname='product'>
<div classname='product_title'>Product 1</div>
<div classname='product_thumbnail'><img src="product1.jpg"></div>
<div classname='product_images'>
<img src="product1_image1.jpg">
<img src="product1_image2.jpg">
</div>
</li>
<li classname='product'>
<div classname='product_title'>Product 2</div>
<div classname='product_thumbnail'><img src="product2.jpg"></div>
<div classname='product_images'>
<img src="product2_image1.jpg">
<img src="product2_image2.jpg">
</div>
</li>
<li classname='product'>
<div classname='product_title'>Product 3</div>
<div classname='product_thumbnail'><img src="product2.jpg"></div>
<div classname='product_images'>
<img src="product3_image1.jpg">
<img src="product3_image2.jpg">
</div>
</li>
</ul>


When I mouse over a product_image I want to change the product_thumbnail src to the product_image src. Its not very hard when I had one list item with the product_thumbnail having an ID

Then I could have done this

var $mainImage = $('#product_thumbnail'),
originalImageSrc = $mainImage.attr('src');

$('.product_images img')
.on('mouseover', function() {
var newImageSrc = $(this).attr('src');
$mainImage.attr('src', newImageSrc);
})
.on('mouseout', function() {
$mainImage.attr('src', originalImageSrc);
});


Working example: JSFiddle

Sadly enough I dont have one list item with an ID.
Of course when I try this code with classes and the html above it will always give me the src back of the first image in the first product_thumbnail div of the first list item.

I hope you guys understand my problem and someone can help me with the classes version of the jQuery example code.

Thanks in advance

Answer

First the html needs fixing - replace className with class. ClassName is the JavaScript attribute name for HTML class. For HTML jsut use class='foo'.

   <ul class='products'>
      <li class='product'>
        <div class='product_title'>Product 1</div>
        <div class='product_thumbnail'><img src="product1.jpg"/></div>
        <div class='product_images'>
          <img src="product1_image1.jpg">
          <img src="product1_image2.jpg">
        </div>
      </li>
      <li class='product'>
        <div class='product_title'>Product 2</div>
        <div class='product_thumbnail'><img src="product2.jpg"/></div>
        <div class='product_images'>
          <img src="product2_image1.jpg">
          <img src="product2_image2.jpg">
          <img src="product2_image3.jpg">
        </div>
      </li>
  </ul>

And the JS now looks like this:

$('.product_images img')
    .on('mouseover', function() {
        var tgt = $(this).closest(".product").find(".product_thumbnail img")
        tgt.data("orig_src", tgt.prop("src")) 
        tgt.prop("src", $(this).prop("src"));
    })
    .on('mouseout', function() {
        var tgt = $(this).closest(".product").find(".product_thumbnail img")
        tgt.prop("src", tgt.data("orig_src"));
    });

The magic is in the selector. closest looks up the DOM from the starting element. We look for the closest element with class=product. When we find it we look for its child with class=product_thumbnail and then the child image of that. This all assumes there is only one occurrence, this code would be different if there were multiple hits.

Having found the target we first store its original src value in its data collection, then we replace the src value with the triggering img src.

On mouse out we take the src we stored in the thumbnails data and replace it.