1
\$\begingroup\$

Im working on a project where a grid of images are loaded all at once. when the mouse is on hover a certain image, a corresponding gif fades in and then fades out when the mouse moves away from the image.

I was able to get a working fiddle with the code i currently have. i have about 20 images that require this desired effect but my code is long and i feel like there is a better way to write my function where it can fade in and out as well as swapping out the images for gifs. Can someone help/point me in the right direction. still learning here!

code:

HTML
<figure>
<img src="http://reneinla.com/tasha/style/images/stills/FORD-SUPER-BOWL.jpg" alt="" class="img-ford" onmouseover="onHover();" onmouseout="offHover();"/>
</figure>
<figure>
<img src="http://reneinla.com/tasha/style/images/stills/OPERATOR.jpg" alt="" class="img-op" onmouseover="onHover1();" onmouseout="offHover1();"/>
</figure>
<figure>
<img src="http://reneinla.com/tasha/style/images/stills/OPERATOR.jpg" alt="" class="img-op1" onmouseover="onHover2();" onmouseout="offHover2();"/>
</figure>
<figure>
<img src="http://reneinla.com/tasha/style/images/stills/FORD-SUPER-BOWL.jpg" alt="" class="img-ford1" onmouseover="onHover3();" onmouseout="offHover3();"/>
</figure>

JAVASCRIPT
$(document).ready(function () {
    onHover();
    offHover();
    onHover1();
    offHover1();
    onHover2();
    offHover2();
    onHover3();
    offHover3();
});
function onHover()
{
    $(".img-ford").attr('src', 'http://reneinla.com/tasha/style/images/gifs/giphy.gif');

}
function offHover()
{
    $(".img-ford").attr('src', 'http://reneinla.com/tasha/style/images/stills/FORD-SUPER-BOWL.jpg');
}
function onHover1()
{
    $(".img-op").attr('src', 'http://reneinla.com/tasha/style/images/gifs/giphy.gif');
}
function offHover1()
{
    $(".img-op").attr('src', 'http://reneinla.com/tasha/style/images/stills/OPERATOR.jpg');
}
function onHover2()
{
    $(".img-op1").attr('src', 'http://reneinla.com/tasha/style/images/gifs/giphy.gif');

}
function offHover2()
{
    $(".img-op1").attr('src', 'http://reneinla.com/tasha/style/images/stills/FORD-SUPER-BOWL.jpg');
}
function onHover3()
{
    $(".img-ford1").attr('src', 'http://reneinla.com/tasha/style/images/gifs/giphy.gif');
}
function offHover3()
{
    $(".img-ford1").attr('src', 'http://reneinla.com/tasha/style/images/stills/OPERATOR.jpg');
}

UPDATE

Thanks for the help! i was able to do some research and found something that works. new fiddle

\$\endgroup\$
  • \$\begingroup\$ Check this demo \$\endgroup\$ – Tushar Jul 19 '17 at 7:24
  • \$\begingroup\$ you have 7 million functions that all do the same thing... why not just make it one function and cal it 7 million times with the required parameters. \$\endgroup\$ – I wrestled a bear once. Jul 19 '17 at 20:15
3
\$\begingroup\$

I think you could reduce a loot your code and do it in a way that it is more clear and effective.

First of all this part you could just remove without concerns:

$(document).ready(function () {
    onHover();
    offHover();
    onHover1();
    offHover1();
    onHover2();
    offHover2();
    onHover3();
    offHover3();
});

The reason, is because those functions are intended to be called on events triggering. This is the logic reason. The functional reason, is that at the end you have the same situation of the beginning.

If your intention was to provide some sort of effect here, it is better to have a dedicated function to this. First of all because those kind of effects could change in time for different reasons than the event handlers. Second reason is because the meaning is much evident.

I thin you could put all the url in your HTML using the data attribute:

<figure>
 <img src="#" alt="" class="img-ford"
   data-out="/tasha/style/images/gifs/giphy.gif"
   data-out="/tasha/style/images/stills/FORD-SUPER-BOWL.jpg"/>
</figure>

You can avoid to place the event handlers directly in HTML code, this could be done in the $(document).ready() section on startup.

Now you can have a function to initialize your images:

function initImages() {
    $('img').each(function(img) {
        $(img).prop('src', $(img).data('out'));
     });
}

Maybe you have to take care of the selector to get only and all the images you want to operate on.

Than start the initialization:

$(function() {
     initImages();
     $('img').on('mouseover', imageMouseOver);
     $('img').on('mouseout', imageMouseOut);
 });

This is the short version of $(document).ready() in jQuery.

Then your functions:

function imageMouseOver(event) {
    $(this).prop('src', $(this).data('over'));
}

And the same for out:

function imageMouseOut(event) {
    $(this).prop('src', $(this).data('out'));
}

Of course you can reduce more with a sort of toggle function, but have used 2 just for sake of clarity.

\$\endgroup\$
0
\$\begingroup\$

Number of functions 2n

You're creating two functions per image one to handle mouseenter event and other to handle mouseout event. If you look at the mouseenter handler of all the images, you'll notice that they are all same. A quick improvement will be to use a single function to handle mouse enter event of all the images. This will reduce the number of functions from 2n to n + 1 where n is the number of images. Is there any way to reduce this to a single function?

Event binding

Don't use inline event handlers. Use jQuery on() method to bind event. See onclick=“” vs event handler

Naming

Using numbers as the suffix to variables/functions means you're repeating same/similar code. Also, the names are not clear. Does onHover2 refer to the function which should be called when hovering second time?

Useless code

The body of ready is completely useless. It is just setting the src attribute value of the image to the same value which is provided in HTML. This can be removed.

Alternative:

You can use hover() to bind mouseenter and mouseleave events on images. On mouseenter, change the image src to the desired image and when mouseleave revert it back to the original.

Also, add a common class to all the images and use this to bind event on them.

$(document).ready(function() {
  var imageSrc = '';
  var hoverImage = 'http://reneinla.com/tasha/style/images/gifs/giphy.gif';

  $('.myImage').hover(function() {
    imageSrc = $(this).attr('src'); // Store the value of original image
    $(this).attr('src', hoverImage);
  }, function() {
    $(this).attr('src', imageSrc);
  });
});
figure img {
  width: 50%;
  height: auto;
  float: left;
  margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<figure>
  <img src="http://reneinla.com/tasha/style/images/stills/FORD-SUPER-BOWL.jpg" alt="" class="myImage" />
</figure>
<figure>
  <img src="http://reneinla.com/tasha/style/images/stills/OPERATOR.jpg" alt="" class="myImage" />
</figure>
<figure>
  <img src="http://reneinla.com/tasha/style/images/stills/OPERATOR.jpg" alt="" class="myImage" />
</figure>
<figure>
  <img src="http://reneinla.com/tasha/style/images/stills/FORD-SUPER-BOWL.jpg" alt="" class="myImage" />
</figure>

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.