0

What I have right now is this, and I'd like to use less code to do the same function. How would I achieve the same output with less lines of code?


// img 1 hover

var image = document.getElementById("rImg");

image.addEventListener('mouseover', function(){
  image.src = "images/blackback.png"
})
image.addEventListener('mouseout', function(){
    image.src = "images/blackfront.png"
  })

// img 2 hover

var img2 = document.getElementById("rMImg");

img2.addEventListener('mouseover', function(){
  img2.src = "images/greyback.png"
})
img2.addEventListener('mouseout', function(){
    img2.src = "images/greyfront.png"
  })

// img 3 hover

var img3 = document.getElementById("lMImg");

img3.addEventListener('mouseover', function(){
  img4.src = "images/navyback.png"
})
img3.addEventListener('mouseout', function(){
    img3.src = "images/navyront.png"
  })
2
  • 1
    What is stopping you from just using img:hover in CSS? Commented Oct 31, 2022 at 16:57
  • Please, since you haven't already, take a tour to learn how this site works (and get your first badge for free!). Commented Oct 31, 2022 at 17:52

2 Answers 2

1

First off, don't use mouseover, mouseout. Use mouseenter/leave instead.
Use classes instead of IDs. Or rather use data-* attribute to store the src to the swap image

const swapImage = (elImg) => {
  const swap = elImg.dataset.imghover; // get the swap src value
  elImg.dataset.imghover = elImg.src;  // store the old src
  elImg.src = swap;                    // apply the new src
}; 

document.querySelectorAll("[data-imghover]").forEach(elImg => {
  elImg.addEventListener("mouseenter", () => swapImage(elImg));
  elImg.addEventListener("mouseleave", () => swapImage(elImg));
});
[data-imghover] {
  max-height: 100px;
  /* other styles here */
}
<img src="images/blackback.png" data-imghover="images/blackfront.png" alt="black">
<img src="images/grayback.png" data-imghover="images/grayfront.png" alt="gray">
<img src="images/navyback.png" data-imghover="images/navyront.png" alt="navy">

Anyways there's a bad UX thing I cannot overlook, and that's that when you hover over the image a request is sent to the server to get that swap image, causing flash of content. Instead you might want to preload your images and don't use JS at all:

.imgHover img {
  max-height: 100px;
}

.imgHover img:last-child {
  transition: 0.24s;
  opacity: 0; /* hide it */
}

.imgHover:hover img:last-child {
  opacity: 1; /* fade in on hover */
}
<span class="imgHover">
  <img src="images/blackback.png" alt="black back">
  <img src="images/blackfront.png" alt="black front">
</span>

<span class="imgHover">
  <img src="images/graykback.png" alt="gray back">
  <img src="images/graykfront.png" alt="gray front">
</span>

<span class="imgHover">
  <img src="images/navykback.png" alt="navy back">
  <img src="images/navykback.png" alt="navy front">
</span>

Sign up to request clarification or add additional context in comments.

Comments

0

You could try something like this:

const images = [
  {
    id: "rImg",
    mouseOver: "images/blackback.png",
    mouseOut: "images/blackfront.png"
  },
  ...the rest of your images here
]

const addImageEventListeners = (images) => {
  images.forEach(image => {
    const el = document.getElementById(image.id)
    el.addEventListener('mouseout', function(){
      el.src = image.mouseOut
    })

    el.addEventListener('mouseover', function(){
      el.src = image.mouseOver
    })
  })
}

images will be an array of your images with ids, and paths on particular event. Then just call addImageEventListeners function with your images array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.