Loop a click event function on “animationend”

只谈情不闲聊 提交于 2021-02-11 12:36:37

问题


I have a question on how to loop a click event itself on animation end

I have 3 pictures i want to rotate on click with an order :

  1. first click on first picture-> first picture rotates,
  2. second click on second picture-> second picture rotates,
  3. third click on third picture-> third picture rotates

the add event listener is the same so i'm trying to loop the function on itself with myEndFunction() but it seems to not be alright

On second click the second picture is moving but i still have to click on first picture

here is the html (very classic one):

<body>

<img id ="first" src= "https://i.ibb.co/bPWLLjV/bookermini.png" alt="booker">

<img id ="second" src= "https://i.ibb.co/KKKqrBp/bobafettmini.png" alt="boba">

<img id ="third" src= "https://i.ibb.co/2yXfmvJ/hommemini.png" alt="joxer">

</body>

here is the css (moving part):

.move {
  position : relative;
  animation: mymove 1s ;
}

@keyframes mymove {
  100%{transform: rotate(360deg); }
}

here is the js code :

var x = document.getElementById("first");
x.addEventListener('click', event => {
    x.classList.add("move");
    x.addEventListener("webkitAnimationEnd", myEndFunction);
    x.addEventListener("animationend", myEndFunction);

    function myEndFunction() {
       x = document.getElementById("second");
    }

});

here is a codepen if you want to try : https://codepen.io/minise/pen/vYGpqJZ

plz i need your help !


回答1:


It seem that you are using an #id selector which returns always the first occurrence, and stops.

My suggestion would be, to use class identifiers instead and reuse your action function.

var version1 = function () {
  // get all containers that has the class rotate-me
  var rotateMe = document.querySelectorAll('.version-1 .rotate-me');
  // define animation duration, this is better than css animationend
  var animationDuration = 1000; // milliseconds

  // recursive animation sequence
  var startSequence = function (classname, items) {
    var [first, ...rest] = items;

    first.classList.add('rotate');

    setTimeout(function () {
      if (rest.length > 0) {
        startSequence(classname, rest)
      }
    }, animationDuration);
  };
  
  // click handle that starts the sequence
  var handleClick = function () {
      startSequence('rotate', rotateMe);
  };
  
  // check if one rotateMe was matched
  if (rotateMe.length > 0) {
    // add you action callback to the first match
    rotateMe[0].addEventListener('click', handleClick);
  }
}

// this version is blocking click before previeous element was clicked
var version2 = function () {
  // get all containers that has the class rotate-me
  var rotateMe = document.querySelectorAll('.version-2 .rotate-me');

  // define animation duration, this is better than css animationend
  var animationDuration = 1000; // milliseconds
  
  // active index
  var activeElement = 0;
  
  // click handle that starts the sequence
  var handleClick = function (index, item) {
      if (index === activeElement) {
        item.classList.add('rotate');
        activeElement += 1;
      }
  };

  for (var i = 0, l = rotateMe.length; i < l; i += 1) {
    // add you action callback to the first match
    rotateMe[i].addEventListener('click', (function (index, item) {
      return function () {
        handleClick(index, item);
      };
    })(i, rotateMe[i]));
  }
}


window.onload = function() {
  version1(); 
  version2(); 
}
.wrapper {
  display: flex;
}

.rotate-me {
  border-radius: 50%;
  overflow: hidden;
  font-size: 0;
}

.rotate-me:first-child {
  cursor: pointer;
}
.rotate-me.rotate {
  cursor: initial;
}
.rotate-me.rotate {
  transition: transform 1s;
  transform: rotate(360deg);
}
<h2>Version 1</h2>
<div class="wrapper version-1">
    <div class="rotate-me">
        <img src="http://placekitten.com/150/150" alt="kitten placeholder">
    </div>
    <div class="rotate-me">
        <img src="http://placekitten.com/150/150" alt="kitten placeholder">
    </div>
    <div class="rotate-me">
        <img src="http://placekitten.com/150/150" alt="kitten placeholder">
    </div>
    <div class="rotate-me">
        <img src="http://placekitten.com/150/150" alt="kitten placeholder">
    </div>
</div>
<h2>Version 2</h2>
<div class="wrapper version-2">
    <div class="rotate-me">
        <img src="http://placekitten.com/150/150" alt="kitten placeholder">
    </div>
    <div class="rotate-me">
        <img src="http://placekitten.com/150/150" alt="kitten placeholder">
    </div>
    <div class="rotate-me">
        <img src="http://placekitten.com/150/150" alt="kitten placeholder">
    </div>
    <div class="rotate-me">
        <img src="http://placekitten.com/150/150" alt="kitten placeholder">
    </div>
</div>



回答2:


var x = document.getElementById("first");x.addEventListener('click', event => {
x.classList.add("move");
  x.addEventListener("webkitAnimationEnd",myEndFunction);
  x.addEventListener("animationend",myEndFunction);});

var y = document.getElementById("second");y.addEventListener('click', event => {
y.classList.add("move");
  y.addEventListener("webkitAnimationEnd",myEndFunction);
  y.addEventListener("animationend",myEndFunction);});

Is this some thing what u are asking for?/




回答3:


Well might has well put the event listener to the picture itself.

So you know what to rotate. Yeah even a div can have an event listener.

Query for the div. add an event listener that onclick the animationPlayState should be running. Else by default put it has paused in css.



来源:https://stackoverflow.com/questions/63781575/loop-a-click-event-function-on-animationend

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!