Ryan Hunter
Ryan Hunter

Reputation: 33

Javascript CSS transition end firing at start of transition

I'm trying to build a simple slideshow where an image slides out for two seconds whilst another image appears beneath it.

(function ready(fn) {
  if (document.readyState != 'loading') {
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
})(init);

function init() {
  var pictureCollection = document.getElementsByClassName('slideshowimg');
  var pictureTracker = document.getElementsByClassName('trackPoint');
  var count = 0;

  //load initial pic
  pictureCollection[count].style.animation = 'fadein10 0.1s forwards';
  pictureTracker[count].style.backgroundColor = 'black';

  //Fade
  var fadetime = setInterval(function() {
    fading()
  }, 5000);

  function fading() {
    pictureCollection[count].style.animation = 'fadeout10 2s forwards';
    pictureTracker[count].style.backgroundColor = 'gray';
    if (count == pictureCollection.length - 1) {
      count = -1;
    }
    count++;
    pictureCollection[count].style.animation = 'fadein10 2s forwards';
    pictureTracker[count].style.backgroundColor = 'black';

  }

  function fixer(direction) {
    //remove event listener to ensure it doesn't reset EVERY transition
    event.target.removeEventListener('transitionend', fixer);
    pictureCollection[count].style.animation = 'fadeout10 0.1s forwards';
    pictureCollection[count].style.transform = 'translateX(0px)';
    //reset counter
    if (count === 3 && direction === "right") {
      count = 0;
      return;
    }
    if (count === 0 && direction === "left") {
      count = 3;
      return;
    }
    if (direction === "right") {
      count++;
    }
    if (direction === "left") {
      count--;
    }

  }

  //add event listener to handle user clicks to each lside
  for (i = 0; i < pictureCollection.length; i++) {
    pictureCollection[i].addEventListener('click', function() {
      //cancel autofade	
      clearInterval(fadetime);
      //check where on pic user clicked
      if (event.clientX > event.target.width / 2) {
        event.target.style.animation = 'nofade10 0.1s forwards';
        pictureTracker[count].style.backgroundColor = 'gray';
        if (count === 3) {
          pictureCollection[0].style.animation = 'fadein5 0.1s forwards';
          pictureTracker[0].style.backgroundColor = 'black';
        } else {
          //bring next pic forwards and unhide
          pictureCollection[count + 1].style.animation = 'fadein5 0.1s forwards';
          pictureTracker[count + 1].style.backgroundColor = 'black';
        }
        //slide out right
        event.target.style.transform = 'translateX(250px)';
        //ensure that when the picture slides out it repositions behind
        pictureCollection[count].addEventListener('transitionend', fixer('right'));

      }
      //or going left . . . 
      else {
        pictureCollection[count].style.animation = 'nofade10 0.1s forwards';
        pictureTracker[count].style.backgroundColor = 'gray';
        if (count === 0) {
          pictureCollection[3].style.animation = 'fadein5 0.1s forwards';
          pictureTracker[3].style.backgroundColor = 'black';
        } else {
          //bring next pic forwards and unhide
          pictureCollection[count - 1].style.animation = 'fadein5 0.1s forwards';
          pictureTracker[count - 1].style.backgroundColor = 'black';
        }
        //slide out left
        event.target.style.transform = 'translateX(-' + pictureCollection[count].width + 'px)';
        //ensure that when the picture slides out it repositions behind
        pictureCollection[count].addEventListener('transitionend', fixer("left"), false);


      }
    });
  }
}
.slideshowimg {
  height: 100%;
  width: 100%;
  position: inherit;
  z-index: 0;
  opacity: 0;
  transition: all 2s ease-in-out;
}
#sliderCase {
  overflow: hidden;
  position: absolute;
  z-index: 5;
  background-color: black;
  height: 150px;
  width: 225px;
}
.trackPoint {
  height: 10px;
  width: 10px;
  margin: 0 2px;
  background-color: gray;
  display: inline-block;
  border-radius: 2em;
  text-align: center;
  position: relative;
  top: 160px;
  left: 75px;
}
@keyframes fadein10 {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
    z-index: 10;
  }
}
@keyframes fadeout10 {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
    z-index: 0;
  }
}
@keyframes fadein5 {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
    z-index: 5;
  }
}
@keyframes nofade10 {
  from {
    opacity: 1;
  }
  to {
    opacity: 1;
    z-index: 10;
  }
}
<!DOCTYPE html>
<html>

<head>
  <meta charset='utf8'>
  <script src='mainedit.js'></script>
  <link rel='stylesheet' href='stylesedit.css' type='text/css'></link>
  <title>Slideshow test</title>
</head>

<body>
  <h1> Slideshow test: </h1>
  <div id='sliderCase'>
    <div style='background-color:red' class='slideshowimg'>pic 1</div>
    <div style='background-color:blue' class='slideshowimg'>pic 2</div>
    <div style='background-color:green' class='slideshowimg'>pic 3</div>
    <div style='background-color:orange' class='slideshowimg'>pic 4</div>
  </div>
  <span class='trackPoint'></span>
  <span class='trackPoint'></span>
  <span class='trackPoint'></span>
  <span class='trackPoint'></span>
</body>

</html>

It seems as if the transition end event is firing as the transition starts. Additionally the movement of slides seems to be inverted in the snippet, yet works locally.

I have used coloured divs in place of images for the sake of this example.

Upvotes: 3

Views: 311

Answers (1)

rgthree
rgthree

Reputation: 7273

This isn't correct:

pictureCollection[count].addEventListener('transitionend', fixer("left"), false);

Here, you are calling and adding the return value of fixer("left") to the event listener, which isn't a valid value anyway.

Upvotes: 2

Related Questions