Home > Software engineering >  How to wait for the end of the element transform property?
How to wait for the end of the element transform property?

Time:04-16

In this example, after the button is clicked, I first want to transform the box and then show an alert. But here, it first show the alert and then do the transform

const clickme = document.getElementById('clickme');
const box = document.getElementById('box');

clickme.addEventListener("click", () => {
        box.style.transform = `rotate(90deg)`;
    const value = parseFloat(box.style.transform.split('rotate(')[1]);
    if(value >= 90) {
        alert('Hello Rotate')
    }
})
#box {
  width: 100px;
  height: 100px;
  background: tomato;
  transition: .200s ease;
}
<div id="box">
  
</div>

<button id="clickme">
  rotate
</button>

CodePudding user response:

That's the limit for transform for you. To achieve best performance, a reliable result and actually use the right tools for the right purpose i'd suggest learning CSS animations with keyframes. It's not that hard and it will allow you to unload some of the tasks from the main thread to the gpu(better SEO and performance). Else there are plenty of libraries that you could use:

For example: https://animejs.com/

CodePudding user response:

In your particular case, the problem is not of the transform property or not having keyframes as Filas' answer pointed out, but instead the problem lies in the nature of Javascript.

const clickme = document.getElementById('clickme');
const box = document.getElementById('box');

clickme.addEventListener("click", () => {
        box.style.transform = `rotate(90deg)`;
    const value = parseFloat(box.style.transform.split('rotate(')[1]);
    if(value >= 90) {
        alert('Hello Rotate')
    }
})

The browser pauses the rendering of the HTML, which is responsible for box.style.transform = 'rotate(90deg)';, and instead prioritizes showing the alert(). Here's a thread that talks about it more.

I assume that in your actual code, you would be using some other function, instead of the alert(). In that case, your code should run as you intended, with the transform occurring first, followed by the subsequent commands.

const clickme = document.getElementById('clickme');
const box = document.getElementById('box');

clickme.addEventListener("click", () => {
        box.style.transform = 'rotate(90deg)';
    const value = parseFloat(box.style.transform.split('rotate(')[1]);
    if(value >= 90) {
        box.style.backgroundColor="green";  //code that isn't an alert()
    }
})
#box {
  width: 100px;
  height: 100px;
  background: tomato;
  transition: .200s ease;
}
<div id="box">
  
</div>

<button id="clickme">
  rotate
</button>

Combine this with a transitionend event, or a setTimeout() function, if you want to sequence the changes in a way that the individual changes/steps are clearly visible to the user.

  • Related