0

I need the element to transition (with an added class), then restore upon completion of said transition (by removing the class). This works, but only on the last element in the collection (no matter how many are there). How can I get the transitionEnd to fire on each element, rather than only the very last one?

I have tried various time outs, etc. in place of the .on('webkitTransitionEnd... nothing has worked so far.

I can not fire them off sequentially as it would take too long. There are dozens that need to be fired simultaneously.

Is there a way to queue this, or am I approaching this the wrong way altogether?

In the real application, text gets changed and other things happen between cycles, that is why can just use keyframes to get it to swing down, wait then go back up.

Thanks in advance, and please advise if I should post/phrase this question differently.

$(document).on("click", "#one", function(e) {
  flipEach()
});


function flipEach(){ 
  // itterate through an array of same-class elements and execute on each
  $(".card").each(function( index ) { 
    // use the index to itterate through the IDs
    position = "#pos_"+(index+1)
    // add the transition class to current item in the each/array
    $( position ).addClass('flipped')
    // change text and remove item on the current item in the each/array after transitionEnd
    $( position ).on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',   
      function(e) {
      // remove the class that flipped it and restore position
      $( position ).removeClass("flipped");  
    });  
});  
};
body {
  display:flex;
  align-items: center;
  text-align: center;
}

.card {
  width:80px;
  height:120px;
  margin:10px;
  font-size:50px;
  text-align:center;
  background-color: gray;
  transform-origin: 0% 100%;
}

.flipped{
  transform: rotateX(-180deg); 
  transition-property: transform;
  transition-duration: 1s; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="one">fipEach</button>

<div id="pos_1" class="card">1</div>
<div id="pos_2" class="card">2</div>
<div id="pos_3" class="card">3</div>
<div id="pos_4" class="card">4</div>
DtM
  • 3
  • 3
  • `position` is a _global_ variable. When any transition ends, why would you expect its value to correspond to the current element as opposed to the last value of `position`? Why not use `$(document).on("transitionend", ".card", function(){ $(this).removeClass("flipped"); });` or something similar? – Sebastian Simon Jan 11 '22 at 02:08
  • @Sebastian Simon, because we all make mistakes sometimes, and we all miss the obvious when we are staring at it too long... Great points! Thanks for your feedback :-) – DtM Jan 11 '22 at 02:40

1 Answers1

0

Your position variable is messing things up. Since you're only trying to use it to reference the current element being iterated over, it's completely superfluous - just use this to reference that element, and add the class and handler to that instead.

$(document).on("click", "#one", function(e) {
  flipEach()
});


function flipEach() {
  // itterate through an array of same-class elements and execute on each
  $(".card").each(function() {
    // add the transition class to current item in the each/array
    $(this).addClass('flipped')
    // change text and remove item on the current item in the each/array after transitionEnd
    $(this).on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',
      function(e) {
        // remove the class that flipped it and restore position
        $(this).removeClass("flipped");
      });
  });
};
body {
  display: flex;
  align-items: center;
  text-align: center;
}

.card {
  width: 80px;
  height: 120px;
  margin: 10px;
  font-size: 50px;
  text-align: center;
  background-color: gray;
  transform-origin: 0% 100%;
}

.flipped {
  transform: rotateX(-180deg);
  transition-property: transform;
  transition-duration: 1s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="one">fipEach</button>

<div id="pos_1" class="card">1</div>
<div id="pos_2" class="card">2</div>
<div id="pos_3" class="card">3</div>
<div id="pos_4" class="card">4</div>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • OMG, So clear and obvious when you point it out! I've been so focused on using the IDs of those elements for other parts of the code, it didn't even dawn on me they aren't needed here at all. Thanks a million, it works like a charm!! – DtM Jan 11 '22 at 02:38