Search code examples
javascriptmouseeventmouseoverimage-gallerymouseenter

Mouseenter event on img inside div works sporadically/erratically


I have a grid of thumbnails. Upon hover I'd like to enlarge the images in the center of the screen. Classic, right?

Each thumbnail is wrapped in a div. When I apply a mouseenter or mouseover event on the img or the div, it simply doesn't work so nicely. I hover with the mouse, and some of the thumbnails enlarge, some don't at all, some need a second or third hover, some flicker.

What's going on? Are the thumbnails maybe "hiding" behind something, therefore not seeing the mouse pointer? Does it have to do with the images being inside divs? (I tried to apply the event listeners to either the imgs or divs, in vain).

<div id="editGrid">
   <div> <img src="Gallery1.png" alt=""> </div>
   <div> <img src="Gallery2.png" alt=""> </div>
   <div> <img src="Gallery3.png" alt=""> </div>
</div>
const divs = document.querySelectorAll('#editGrid > div')
const images = document.querySelectorAll('#editGrid > div > img')
const bigImageArea = document.querySelector('#edit')
let bigImage

divs.forEach((image, i) => {
    image.addEventListener('mouseenter', () => {
        bigImage = images[i].cloneNode(false)
        bigImage.style.position = 'fixed'
        bigImage.style.left = '50vw'
        bigImage.style.top = '50vh'
        bigImage.style.transform = 'translate(-50%, -50%)'
        bigImageArea.appendChild(bigImage)
    })
    image.addEventListener('mouseleave', () => {
        bigImageArea.removeChild(bigImage)
    })
})

Solution

  • It seems your #edit element overlaps the images and triggers mouseleave event. You can disable mouse events on that element with pointer-events: none;, also avoid inline styles:

    const divs = document.querySelectorAll('#editGrid > div')
    const images = document.querySelectorAll('#editGrid > div > img')
    const bigImageArea = document.querySelector('#edit')
    let bigImage
    
    divs.forEach((image, i) => {
      image.addEventListener('mouseenter', () => {
        bigImage = images[i].cloneNode(false)
        bigImageArea.appendChild(bigImage)
      })
      image.addEventListener('mouseleave', () => {
        bigImageArea.removeChild(bigImage)
      })
    })
    #edit
    {
      pointer-events: none;
    }
    
    #edit > img
    {
      position: fixed;
      left: 50vw;
      top: 50vh;
      transform: translate(-50%, -50%);
    }
    
    #editGrid > div
    {
      width: 30%;
    }
    #editGrid img
    {
      width: 100%;
    }
    <div id="editGrid">
      <div><img src="https://lh3.googleusercontent.com/taykG37GWDgY-FGkdogDvsHSJMUGRMvkuVRT6yR-5UNkKvGRKeRlpGYXlslocOcS0txlfUdGW59JGtzADknxbMqnh6AtVCv9EXyB8nHp80YsRNA0Yw=w512-h342-n-l50-sg-rj" alt=""></div>
      <div><img src="https://lh3.googleusercontent.com/fl-GT6w3Ls6RT4vYnbkuYUyLY3lZJH8VtZ7xzxiym9YYaoVRCnZehdz6Icd0oAf6i3H9-O5cCNs6eunlxWr_Csstgsb98DdzNdLFBOlhw9NUfHdyuQjI=w384-h512-n-l50-sg-rj" alt=""></div>
      <div><img src="https://lh3.googleusercontent.com/9pPCK70Rw0k3wethMHb1qMaIB0VjeWLy57vYgSzKbF7oJuvO2nA0Nakk-95cvibWUDcEhYkfCKvdPKT03tXZd4M5jdhIEibLO9qw-XE=w512-h342-n-l50-sg-rj" alt=""></div>
    </div>
    <div id="edit"></div>