Search code examples
javascripthtmlcsscss-transitionscss-transforms

Why is the transition not working when I am adding the element?


I am creating an element each time when the function is called, but the transition is not always working. I wanted a message coming from the top of the screen but it is adding the element instantly without applying the transition. An HTML example is provided for you to try it. This is the Codepen link https://codepen.io/arijit1st/pen/YzBvMrP.

HTML:


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div class="d1" id="d1">

  <button class="b1" id="b1">Click here!</button>

</div>
</body>
</html>

JavaScript:

const d1 = document.getElementById("d1")
const b1 = document.getElementById("b1")
let bottomCount = 160
let d3IdCount = 3
let svgIdCount = 4
let messagesCount = 1
let d3ST1 = null
let d3ST2 = null
let d3ST3 = null
let d3AlreadyExists = false

async function errorMessageUI(message){

    const d3 = document.createElement("div")

    d3.classList.add("d3")
    d3.id = "d3"

    const d3Exists = document.querySelector(".d3")

if(d3Exists){

      messagesCount++
      bottomCount += 100
      d3IdCount += 1
      svgIdCount += 1
      d3AlreadyExists = true
}

else if(!d3Exists){
  messagesCount = 1
  bottomCount = 160
  d3IdCount = 3
  svgIdCount = 4
  d3AlreadyExists = false
}

  d3.id = `${d3IdCount}`

  d1.append(d3)

    d3.innerHTML = `${message} <p class="p3" id="p3">  ${messagesCount > 1? "x" : ''}${messagesCount > 1? messagesCount : ''} </p> <svg style="opacity: 60%" class="svg4" id="svg${svgIdCount}" width="8%" height="54%" viewBox="0 0 16 16"><path class="path4" id="path4" d="m4.12 6.137 1.521-1.52 7 7-1.52 1.52z"/><path class="path4" id="path4" d="m4.12 11.61 7.001-7 1.52 1.52-7 7z"/></svg>`

    d3ST1 = setTimeout(() => {
      d3.style.transform = `translateY(${bottomCount}%)`
    }, 0)

d3ST2 = setTimeout(() => {


d3.style.transform = "translateY(-300%)"
clearTimeout(d3ST1)
clearTimeout(d3ST2)

}, 5000)

setTimeout(() => {
d3.remove()
}, 5201)

    const crossSVG = document.getElementById(`svg${svgIdCount}`)

    d3.addEventListener("mouseover", () => {

      crossSVG.style.opacity = "100%"

    })

    d3.addEventListener("mouseout", () => {

      crossSVG.style.opacity = "60%"

    })

    crossSVG.addEventListener('click', () =>{

      clearTimeout(d3ST1)
      clearTimeout(d3ST2)

      setTimeout(() => {
        d3.remove()
      }, 201)

      d3.style.transform = "translateY(-300%)"

    })
  }

b1.addEventListener("click", () => {

  errorMessageUI("hello")

})

CSS:


.d3{
position: absolute;
    font-family: sans-serif;
    transform: translateY(-300%);
    transition: transform 150ms ease !important;
    display: flex;
    background: rgba(239, 87, 87, 0.83);
    width: 20%;
    min-height: 5%;
    text-align: center;
    border-radius: 5px;
    border-left: 4px solid #af0e0edb;
    color: #990e0e;
    font-size: 1.07rem;
    justify-content: center;
    align-items: center;

}

I excepted that the transition will work always when an element is added, but the transition is not always working.


Solution

  • Proplem

    You have set a timeout and the cleared it directly. That would, for most of the time, not call the function — especially the last one. It is specifically at...

    d3ST2 = setTimeout(() => {
      d3.style.transform = "translateY(-300%)"
      clearTimeout(d3ST1)
      clearTimeout(d3ST2)
    }, 5000)
    

    Solution

    You can weather call the function one last time at the end, or just delete the clearTimeout(). This is a working Codepen.io example.