简体   繁体   中英

In JavaScript, how can I add animation effect on every image in a modal gallery?

I have a gallery of images, every one of which gets opened in a modal mode on click. I want to add an animation effect to each one of them to be shown when we next and previous buttons are clicked. I added the animation style to my JS code, however it doesn't work as expected. It only works on the first click, not the rest.

Here is my code:


    var prev = document.querySelector("#prev");
    var next = document.querySelector("#next");
    next.addEventListener("click", nextImage);
    modalImg.addEventListener("click", nextImage);
    prev.addEventListener("click", previousImage);

    function nextImage() {
      if (currentIndex < imgArr.length - 1) {
        currentIndex++;
        modalImg.src = imgArr[currentIndex].style.backgroundImage
          .slice(4, -1)
          .replace(/"/g, "");
      }
      modalImg.style.animation = "fadeInLeft .4s both";
    }

    function previousImage() {
      if (currentIndex > 0) {
        currentIndex--;
        modalImg.src = imgArr[currentIndex].style.backgroundImage
          .slice(4, -1)
          .replace(/"/g, "");
      }
      modalImg.style.animation = "fadeInLeft .4s both";
    }

    @keyframes fadeInLeft {
      0% {
        opacity: 0;
        -webkit-transform: translateX(-20px);
        -ms-transform: translateX(-20px);
        transform: translateX(-20px);
      }
      100% {
        opacity: 1;
        -webkit-transform: translateX(0);
        -ms-transform: translateX(0);
        transform: translateX(0);
      }
    }

You could achive it via manipulate animation via property animationName or via manipulate via class name, that have defined animation.

See example

In any case you should remove animation when it complete

function onAnimationEnd(){
/*
  // Options 1: Manipulate class name
  this.classList.remove('fade')
*/
  imgContainer.style.animationName = 'none';
}
imgContainer.addEventListener('animationend', onAnimationEnd);

You could simplify to avoid repetition:

const prev = document.querySelector("#prev");
const next = document.querySelector("#next")
prev.addEventListener("click", prevImage);
next.addEventListener("click", nextImage);
modalImg.addEventListener("click", nextImage);

function animate(i) {
  modalImg.src = imgArr[i].style.backgroundImage
    .slice(4, -1)
    .replace(/"/g, "");
  modalImg.style.animationName = "fadeInLeft";
}

function nextImage() {
  currentIndex = (currentIndex + 1) % imgArr.length;
  animate(currentIndex)
}

function prevImage() {
  currentIndex = (currentIndex + imgArr.length - 1) % imgArr.length;
  animate(currentIndex)
}

Or use only one event listener (no need for prev and next variables):

function animate(i) {
  modalImg.src = imgArr[i].style.backgroundImage
    .slice(4, -1)
    .replace(/"/g, "");
  modalImg.style.animationName = "fadeInLeft";
}

function showImage(elem) {
    if (elem.id === "next" || elem.id === "modalImg") {
        currentIndex = (currentIndex + 1) % imgArr.length;
    } else if (elem.id === "prev") {
        currentIndex = (currentIndex + imgArr.length - 1) % imgArr.length;
    } else {
        return currentIndex
    }
    animate(currentIndex)
}

window.addEventListener("click", function(e) {
    showImage(e.target)
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM