1
\$\begingroup\$

I have a very simple webpage that contains 4 color images. When I hover over any of the images the original (xxxx1.jpg) is replaced by a black and white version (xxxxx2.jpg) of the same image, and then it reverts back to the original image after hover.

I'm declaring the same variable for both handlerIn and handlerOut:

var src = $(this).attr("src")

Can I declare the var just once somehow? I just can't seem to figure this out myself.

$(document).ready(function(){
    $( "img" ).hover(
        function() {
            var src = $(this).attr("src").replace("1.jpg", "2.jpg");
            $(this).attr("src", src);
        }, 
        function() {
            var src = $(this).attr("src").replace("2.jpg", "1.jpg");
            $(this).attr("src", src);
        }
    );
});
\$\endgroup\$
  • 4
    \$\begingroup\$ Use CSS background-image to set the image on element, on :hover change the background image. \$\endgroup\$ – Tushar Dec 19 '16 at 5:49
  • \$\begingroup\$ @Tushar I'll definitely do that for the practice, but this is an assignment for school that needs to be done entirely in jquery, there is no css for this page. \$\endgroup\$ – Krista P Dec 19 '16 at 6:01
  • \$\begingroup\$ @nnnnnn Thanks, this works. I'm literally on day 2 of jquery so I don't quite understand how this is working but I'll start picking it apart to figure it out:) \$\endgroup\$ – Krista P Dec 19 '16 at 6:24
  • \$\begingroup\$ I've expanded a little on that comment in an answer (so have deleted the comment). \$\endgroup\$ – nnnnnn Dec 19 '16 at 6:32
  • \$\begingroup\$ You can use the same approach, with jQuery hover() and CSS classes and toggleClass in callbacks. \$\endgroup\$ – Tushar Dec 19 '16 at 6:47
2
\$\begingroup\$

The first thing I would do to make the code shorter is to take advantage of the fact that many jQuery methods like .attr() accept a function as the second argument, allowing you to replace this:

var src = $(this).attr("src").replace("1.jpg", "2.jpg");
$(this).attr("src", src);

...with this:

$(this).attr("src", function(i, v) { return v.replace("1.jpg", "2.jpg"); });

(and similar in the other function.) What this does is call the function in the second argument with the current value of the attribute as the v argument, so you don't need a separate call to .attr() to find out what the current value is, and you don't need the src variable.

Then I'd change the .hover() code to pass a single function to run on mouseenter and mouseleave, and use the event object to check whether it is mouseenter or mouseleave:

$(document).ready(function(){
  $("img").hover(function(e) {
    $(this).attr("src", function(i, v) {
      return v.replace(/[12]\.jpg/, (e.type === "mouseenter" ? "2" : "1") + ".jpg");
    });
  });
});

This uses a regular expression /[12]\.jpg/ with .replace() to find a string ending with "1.jpg" or "2.jpg", and replace it with a value depending on the event.type.

Demo: https://jsfiddle.net/g5ncjjxo/

\$\endgroup\$
  • \$\begingroup\$ @Tushar - I didn't mention CSS in my answer because of the comments above about having to do it without CSS. But how would you use CSS classes to change images with different sources? \$\endgroup\$ – nnnnnn Dec 19 '16 at 7:17
  • \$\begingroup\$ Fair Enough. Using CSS, instead of using <img /> use other element and add class to it. The CSS Class will have background-image: 1.jpg and some other positioning styles. Another class will have background-image: 2.jpg which can be used to change the background image. In hover() callbacks $(this).toggleClass('originalImage hoverImage') \$\endgroup\$ – Tushar Dec 19 '16 at 7:22
  • \$\begingroup\$ @Tushar - I meant, how would you apply that to multiple different elements in the page, each of which has its own pair of images, without having to create classes for each element? \$\endgroup\$ – nnnnnn Dec 19 '16 at 9:27

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.