0

I am attempting to make a gallery, and in that gallery I want to have it so that when I mouseover a thumbnail I want to have a bigger version of that image pop up at the cursor, and then for it to disappear when you remove the cursor from the thumbnail.

Is there anyway to do this without hardcoding two sets of the image in the HTML code and just use the available images to, for example, onmouseover create an element that shows the larger version of the image and using the img src of the hovered image that will then go away when removing the cursor from the element?

If I tried to explain it with code I guess it would look something like:

const image = document.getElementsByClassName('image');

for (let i = 0; i < image.length; i++) {

    const picture = image[i];

    picture.onmouseover = () => {
       const img = document.createElement('img');
       img.src = picture.src; //using the source of the available image to display it in a larger version
    }
}

...and then removing the element when onmouseout.

I'm sure there are some libraries that might make this easier, like jQuery, but I am trying to make it in JavaScript to understand it better.

Zansas
  • 3
  • 1
  • 4
  • You do not want to create the element again, just use javascript to add a css class to the image on hover, which will change its position and scale it. – Spangle Oct 13 '19 at 23:55
  • That is not really what i was going for, i want the gallery to be of thumbnails and not really change in layout - but have another element pop up when hovering that changes the image in a larger format. The solutions i have seen when searcing around has all been with hardcoding 2 sets of images in the html, one that is shown as a thumbnail and one that is of the larger size that has `display: none;` and that you change that to `display: block;` when hovering over the img (or usually it is onclick and not onmouseover, but i think you know what i mean). – Zansas Oct 14 '19 at 20:08
  • I get what you are talking about too. Take a look at https://galleria.io/ we use that at my work. – Spangle Oct 14 '19 at 22:49

1 Answers1

1

Look at the snippet below.

The HTML part is so simple. You have some images in screen with class .image.

CSS part is so simple too. You have two classes:

  • image class
  • and cloned image class

I did not comment to JS part but the idea behind that is:

  • I use closure and use document as parameter for better performance
  • then a docReady function listen to document's state to be ready

For more information about docReady function see this link

  • after document content loaded, get all images with getElementsByClassName function
  • then in a for loop, iterate through them and create a event listener for mouseenter and mouseleave
  • in mouseenter event, create an element then add id, class and src to it and manipulate top and left (depends on where you want it to be. Use position engine!). After all add/append it to body.
  • and in mouseleave event listener, find cloned image and remove it from document's body.

It maybe not compatible with all browsers! use jQuery for that purpose.

Improve it and fix minor bugs then you can simply use it.

I hope it helps. sorry for my bad english :)

// This is a closure
(function(document) {
  function docReady(fn) {
    // see if DOM is already available
    if (document.readyState === "complete" || document.readyState === "interactive") {
      // call on next available tick
      setTimeout(fn, 1);
    } else {
      document.addEventListener("DOMContentLoaded", fn);
    }
  }

  docReady(function() {
    var images, image, id, clone;
    var i, len;
    var clone_cls = 'clone-image';
    var bound;

    images = document.getElementsByClassName('image');
    len = images.length;

    for (i = 0; i < len; i++) {
      image = images[i];

      // Mouse enter event
      image.addEventListener('mouseenter', function() {
        id = uniqueId();
        //-----
        this.setAttribute('data-clone-id', id);
        //-----
        clone = document.createElement('IMG');
        clone.src = this.src;
        clone.classList.add(clone_cls);
        clone.id = id;
        //-----
        bound = this.getBoundingClientRect();
        clone.style.top = (bound.top + pageYOffset) + 'px';
        // clone.style.right = document.body.offsetWidth - (bound.right + pageXOffset) + 'px';
        clone.style.left = (bound.left + pageXOffset) + 'px';
        document.body.appendChild(clone);
      });
      // Mouse leave event
      image.addEventListener('mouseleave', function() {
        id = this.getAttribute('data-clone-id');
        if (id) {
          this.removeAttribute('data-clone-id');
          clone = document.getElementById(id);
          if (typeof clone !== 'undefined') {
            clone.remove();
          }
        }
      });
    }

    function uniqueId() {
      var name, num, str, test;
      //-----
      name = 'clone';
      do {
        num = Math.floor(Math.random() * 100000);
        str = name + num;
        test = document.getElementById(str);
      } while (test && test.length);

      return str;
    }
  });
})(document);
.image {
  display: inline-block;
  width: 300px;
  height: 300px;
}

.clone-image {
  position: absolute;
  max-width: 100%;
  width: auto;
  height: auto;
  max-height: 100%;
  z-index: 1001;
  pointer-events: none;
}
<div>
  <img src="https://dummyimage.com/900x900/40495c/ffffff.jpg&text=Image 1" alt="dummy image" class="image">
  <img src="https://dummyimage.com/900x900/40495c/ffffff.jpg&text=Image 2" alt="dummy image" class="image">
  <img src="https://dummyimage.com/900x900/40495c/ffffff.jpg&text=Image 3" alt="dummy image" class="image">
  <img src="https://dummyimage.com/900x900/40495c/ffffff.jpg&text=Image 4" alt="dummy image" class="image">
</div>
MMDM
  • 465
  • 3
  • 11
  • Thank you for you help! That was very much what i had in mind! I found no errors with your english, it was very well documented and explained. – Zansas Oct 15 '19 at 02:12