Is my 'transitioned' event listener not working?

I’m expecting the top paragraph to fade out as the bottom paragraph fades in but the element is getting removed from the DOM before the animation happens.

When there are 5 paragraphs in the collection (querySelectorAll) the 0 index gets removed. The CSS animation works as expected for createElement not for .remove()

What am I missing?

function addPara() {
  let r = Math.floor(Math.random() * 9);
  let g = Math.floor(Math.random() * 9);
  let b = Math.floor(Math.random() * 9);
  let bg = `#${r}${g}${b}`
  let qsaPara = document.querySelectorAll('p');
  const para = document.createElement('p')
  para.style.backgroundColor = bg
  para.style.height = '3rem'
  document.body.appendChild(para)
  let paraArray = Array.from(qsaPara);
  let l = paraArray.length
  let clVal = para.classList.value;

  function parRemove() {
    paraArray[0].remove();
    paraArray[0].removeEventListener('transitionend', parRemove)
  }


  if (paraArray.length >= 5) {
    paraArray[0].classList.add('fall');
    // para.innerHTML += `class:${clVal}`

    paraArray.forEach((para, i) => {
      para.nextSibling.innerHTML = `index ${i}, collection length${l}, class:${clVal}`;
    });

          //------------------------
    paraArray[0].addEventListener('transitionend', parRemove, false);
    //----------------------

  } else if (paraArray.length <= 5) {
    paraArray.forEach((para, i) => {
      para.innerHTML = `index ${i}, collection length${l}, class:${clVal}`
    })
  }

}

const paraTimer = setInterval(addPara, 2000);
p {
  color: white;
  width: 100%;
  animation-name: fade-in;
  animation-duration: 1s;
  animation-iteration-count: 1;
  transition: all ease-in-out 1s;
}

.fade {
  animation-name: fade-out;
  animation-duration: 1s;
  animation-iteration-count: 1;
}

@keyframes fade-in {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@keyframes fade-out {
  from {
    opacity: 1;
  }

  to {
    opacity: 0;
  }
}

17 thoughts on “Is my 'transitioned' event listener not working?”

  1. It seems to be an issue with transitionend expecting CSS transform and NOT animation.

    Use webkitAnimationEnd / animationend event listeners for css animations and use webkitTransitionEnd / ‘transitionend’ event listeners for css transform transitions.

    If ya didn’t know, well now ya know.

    I updated the answer with a fix for my original animation

     function addPara() {
       let r = Math.floor(Math.random() * 9);
       let g = Math.floor(Math.random() * 9);
       let b = Math.floor(Math.random() * 9);
       let bg = `#${r}${g}${b}`
       let qsaPara = document.querySelectorAll('p');
       const para = document.createElement('p')
       para.style.backgroundColor = bg
       para.style.height = '3rem'
       document.body.appendChild(para)
       let paraArray = Array.from(qsaPara);
       let l = paraArray.length
       let clVal = para.classList.value;
    
       function parRemove() {
         
         paraArray[0].remove()
        // paraArray[0].removeEventListener('transitionend', parRemove)
        
        paraArray[0].removeEventListener("webkitAnimationEnd", parRemove);
        paraArray[0].removeEventListener("animationend", parRemove, false);
    
    
       }
    
       if (paraArray.length >= 5) {
         paraArray.forEach((para, i) => {
           para.nextSibling.innerHTML = `index ${i}, collection length${l}`;
    
    
       // for css transition
       /*        paraArray[0].classList.add('fall');
              paraArray[0].addEventListener('transitionend', parRemove, false) */
    
       // for css animation
       paraArray[0].classList.add('fade');
       paraArray[0].addEventListener('webkitAnimationEnd', parRemove, false); // Code for Chrome, Safari and Opera
       paraArray[0].addEventListener("animationend", parRemove, false);
     });
    
        
    
    
    
       } else if (paraArray.length <= 5) {
         paraArray.forEach((para, i) => {
           para.innerHTML = `index ${i}, collection length${l}`
         })
       }
     }
    
     const paraTimer = setInterval(addPara, 2000);
    p {
      opacity: 1;
      color: white;
      width: 100%;
      animation-name: fade-in;
      animation-duration: 1s;
      animation-iteration-count: 1;
      /* transition: all ease-in-out 1s; */
    }
    
     .fade {
      animation-name: fade-out;
      animation-duration: 1s;
      animation-iteration-count: 1;
    } 
    
    @keyframes fade-in {
      from {
        opacity: 0;
      }
    
      to {
        opacity: 1;
      }
    }
    
    @keyframes fade-out {
      from {
        opacity: 1;
      }
    
      to {
        opacity: 0;
      }
    }
      /*
       .fall {
      transform: scale(3);
      transform: translateY(9rem);
      opacity: 0;
    }. */
    Reply

Leave a Comment