I want to do a CSS3 transition in one-way. For example, I want to highlight some element by setting it's background-color: yellow; immediately, and set it back to background-color: white; with one-way transition.
I tried to use JavaScript to achieve this like this:
const highlightBtn = document.getElementById("highlightBtn");
const highlightToggleBtn = document.getElementById("highlightToggleBtn");
const highlightTimeoutBtn = document.getElementById("highlightTimeoutBtn");
const bodyClassList = document.getElementsByTagName("body")[0].classList;
highlightBtn.addEventListener("click", () => {
bodyClassList.add("highlight");
bodyClassList.remove("highlight");
/*
This doesn't work, either.
bodyClassList.toggle("highlight");
bodyClassList.toggle("highlight");
*/
});
highlightToggleBtn.addEventListener("click", () => {
bodyClassList.toggle("highlight");
});
highlightTimeoutBtn.addEventListener("click", () => {
bodyClassList.add("highlight");
setTimeout(() => {bodyClassList.remove("highlight");});
/*
This works, too.
bodyClassList.toggle("highlight");
setTimeout(() => {bodyClassList.toggle("highlight");});
*/
});
body {
transition: background-color 1s ease;
background-color: white;
}
body.highlight {
transition: background-color 0s ease;
background-color: yellow;
}
<button id="highlightBtn">
Highlight
</button>
<button id="highlightToggleBtn">
Highlight Toggle
</button>
<button id="highlightTimeoutBtn">
Highlight Timeout
</button>
The problem is, if I toggle the class once at a time, transition works perfectly.
// This works fine.
highlightToggleBtn.addEventListener("click", () => {
bodyClassList.toggle("highlight");
});
However, for the original goal, I want to highlight the element, so I put add/remove to the same element just want to see the one-way transition, it failed.
highlightBtn.addEventListener("click", () => {
bodyClassList.add("highlight");
bodyClassList.remove("highlight");
/*
This doesn't work, either.
bodyClassList.toggle("highlight");
bodyClassList.toggle("highlight");
*/
});
But, if I use setTimeout with delay is 0 ms, the result is ideal.
highlightTimeoutBtn.addEventListener("click", () => {
bodyClassList.add("highlight");
setTimeout(() => {bodyClassList.remove("highlight");});
/*
This works, too.
bodyClassList.toggle("highlight");
setTimeout(() => {bodyClassList.toggle("highlight");});
*/
});
Why the second method doesn't work? Is putting the removeClass in setTimeout the best solution? I also tried put a delay in my body's transition CSS like: transition: background-color 1s ease 1ms;, but it doesn't work, either.