0

I have the following HTML. Essentially 4 similarly styled boxes that are inline with eachother. When I hover each individual box, i'm trying to change the img src to the data-alt-src, only for the individual div thats being hovered.

I have the jQuery further below to do this. But it is very hard-coded, i'm wondering if there is a better way of doing this? Also with an ease-in-out of .4s would be a huge help as I already have the CSS doing this for the background color. The main source image is blue and the alt source is white.

<div class="skillsBox">
    <div class="skill_div">
        <div class="skill_img">
            <img src="css/house.png" data-alt-src="css/house2.png" alt="House"/>
        </div>
        <div class="skill_title">
            <h3>Repairs</h3>
        </div>
    </div>

    <div class="skill_div">
        <div class="skill_img">
            <img src="css/settings.png" data-alt-src="css/settings2.png" alt="Repair"/>
        </div>
        <div class="skill_title">
            <h3>Improvement</h3>
        </div>
    </div>

    <div class="skill_div">
        <div class="skill_img">
            <img src="css/shopping-cart.png" data-alt-src="css/shopping-cart2.png" alt="Cart"/>
        </div>
        <div class="skill_title">
            <h3>Affordable</h3>
        </div>
    </div>

    <div class="skill_div">
        <div class="skill_img">
            <img src="css/like.png" data-alt-src="css/like2.png" alt="Like"/>
        </div>

        <div class="skill_title">
            <h3>Satisfaction</h3>
        </div>
    </div>
</div>

Here is the jQuery:

$(".skill_div:nth-of-type(1)").hover(
    function () {
        var $this = $(".skill_div:nth-of-type(1) img");
        var newSource = $this.data('alt-src');
        $this.data('alt-src', $this.attr('src'));
        $this.attr('src', newSource)
    });

$(".skill_div:nth-of-type(2)").hover(
    function () {
        var $this = $(".skill_div:nth-of-type(2) img");
        var newSource = $this.data('alt-src');
        $this.data('alt-src', $this.attr('src'));
        $this.attr('src', newSource)
    });

$(".skill_div:nth-of-type(3)").hover(
    function () {
        var $this = $(".skill_div:nth-of-type(3) img");
        var newSource = $this.data('alt-src');
        $this.data('alt-src', $this.attr('src'));
        $this.attr('src', newSource)
    });

$(".skill_div:nth-of-type(4)").hover(
    function () {
        var $this = $(".skill_div:nth-of-type(4) img");
        var newSource = $this.data('alt-src');
        $this.data('alt-src', $this.attr('src'));
        $this.attr('src', newSource);
    });

Thanks a bunch, I did try to research the answer but could not find with my particular key-words, if this has been done before I do apologise.

Ele
  • 33,468
  • 7
  • 37
  • 75
Rio Karim
  • 3
  • 2

2 Answers2

0

You can simply assign an event handler to each .skill_div and access each specific one inside the handler function using $(this):

$(".skill_div").on('mouseenter mouseleave', 
  function () {
    var $this = $(this).find("img");
    var newSource = $this.data('alt-src');
    $this.data('alt-src', $this.attr('src'));
    $this.attr('src', newSource)
  }
);

A solution that does not even require Javascript would be this CSS approach:

<div class="skill_div">
    <div class="skill_img">
        <img src="css/settings.png" alt="Repair"/>
        <img src="css/settings2.png" alt="Repair"/>
    </div>
    <div class="skill_title">
        <h3>Improvement</h3>
    </div>
</div>
<style type="text/css">
  .skill_div img { transition-duration: .3s; }
  .skill_div img + img { opacity: 0; }
  .skill_div img:first-of-type { position: absolute; }
  .skill_div:hover img:first-of-type { opacity: 0; }
  .skill_div:hover img + img { opacity: 1; }
</style>
connexo
  • 53,704
  • 14
  • 91
  • 128
  • 1
    The pseudo event `hover` has been removed from jq1.9 – A. Wolff Dec 31 '17 at 16:13
  • Thx for the hint. Mean to use `mouseover` anyway. – connexo Dec 31 '17 at 16:15
  • 1
    np but you should use `mouseenter` – A. Wolff Dec 31 '17 at 16:16
  • Explain the downside of mouseover compared to mouseenter please. – connexo Dec 31 '17 at 16:16
  • 1
    mouseover will be fired multiple times due to event bubbling, see e.g: https://stackoverflow.com/questions/1104344/what-is-the-difference-between-the-mouseover-and-mouseenter-events – A. Wolff Dec 31 '17 at 16:19
  • So as mouseenter will not react to event bubbling, what if the img sits right at the outermost edge of the containing div, will the containing div receive the mouseenter event at all? – connexo Dec 31 '17 at 16:22
  • It will be fired. The thing is that mouseover will be fired each time the cursor go directly over it. It means if you enter the container, it will be fired, then you set cursor over nested image, a mouseout event will be fired. And then you go over the container again, mouseover will be fired a second time. You don't have this issue with mouseenter/mouseleave events – A. Wolff Dec 31 '17 at 16:26
  • does work but it is missing an extra parenthesis at the end. – Rio Karim Dec 31 '17 at 16:30
  • not sure about this answer as its causing alot of glitches with rapid mouse movement causing the image to drop off completely. – Rio Karim Dec 31 '17 at 16:33
  • Replace `mouseover` by `mouseenter`. Apart from that, this does exactly what your code did. I just sharply shortened your code. – connexo Dec 31 '17 at 16:34
  • awesome, I figured another way of doing it was to take the image out of the markup and set it as a CSS background. Then on hover change the url of the background image. – Rio Karim Jan 01 '18 at 09:20
0

Thanks for all the help in the comments. I have now made it much easier on the eyes with the following code:

  $(".skill_div").mouseenter(
   function () {
    var $this = $(this).find("img");
    var newSource = $this.data('alt-src');
    $this.data('alt-src', $this.attr('src'));
    $this.attr('src', newSource)
   }
  )

  $(".skill_div").mouseleave(
   function () {
   var $this = $(this).find("img");
   var newSource = $this.data('alt-src');
   $this.data('alt-src', $this.attr('src'));
   $this.attr('src', newSource)
  }
 )

Please feel free to add further if this can be better improved.

Rio Karim
  • 3
  • 2
  • Check my updated answer. You can define both in one step since the handler functions are identical. – connexo Dec 31 '17 at 17:16
  • Also added a pure CSS approach that also involves a smooth transition from one image to another. – connexo Dec 31 '17 at 17:30