The best way to explain my problem is these are two demos:
And that are they:
Demo 1 (works as expected in chrome, in firefox it doesn't work)
let handler = function () {
block.classList.add("visible");
requestAnimationFrame(() => block.classList.add("move"));
block.addEventListener(
"transitionend",
() => {
console.log("style is removed");
this.addEventListener("click", handler, { once: true });
block.classList.remove("move");
},
{ once: true }
);
};
btn.addEventListener("click", handler, { once: true });
.main {
display: none;
width: 100px;
height: 100px;
background: red;
transition: all 5.5s ease;
}
.visible {
display: block;
}
.move {
transform: translateX(100px);
background: blue;
}
<div id="block" class="main"></div>
<button id="btn">Animate</button>
Demo 2 (works incorrect)
let handler = function () {
block.classList.add("visible");
block.classList.add("move");
block.addEventListener(
"transitionend",
() => {
console.log("style is removed");
this.addEventListener("click", handler, { once: true });
block.classList.remove("move");
},
{ once: true }
);
};
btn.addEventListener("click", handler, { once: true });
.main {
display: none;
width: 100px;
height: 100px;
background: red;
transition: all 5.5s ease;
}
.visible {
display: block;
}
.move {
transform: translateX(100px);
background: blue;
}
<div id="block" class="main"></div>
<button id="btn">Animate</button>
I'll fast emphasize differences between two demos:
- first demo has requestAnimationFrame
<div>
block has class "visible" before starting a click handler in first demoIn the click handler, it has code for adding class "visible" in the second demo
So main question is: Why second demo doesn't fire transitionend event and why I don't see transition?
Extra demo
let handler = function () {
alert(1);
block.classList.add("visible");
alert(2);
setTimeout(() => {
alert(4);
block.classList.add("move");
alert(5);
});
block.addEventListener(
"transitionend",
() => {
console.log("style is removed");
this.addEventListener("click", handler, { once: true });
block.classList.remove("move");
},
{ once: true }
);
alert(3);
};
btn.addEventListener("click", handler, { once: true });
.main {
display: none;
width: 100px;
height: 100px;
background: red;
transition: all 5.5s ease;
}
.visible {
display: block;
}
.move {
transform: translateX(100px);
background: blue;
}
<div id="block" class="main"></div>
<button id="btn">Animate</button>
Checkout it in chrome and firefox, seems what some part of code invokes repainting earlier, if it is not, correct me and explain why.