Home > Back-end >  On mouse hover changing picture with JavaScript with less code
On mouse hover changing picture with JavaScript with less code

Time:11-01

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"
  })

CodePudding user response:

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 >
  <img src="images/blackback.png" alt="black back">
  <img src="images/blackfront.png" alt="black front">
</span>

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

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

CodePudding user response:

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.

  • Related