我想单向地进行CSS3转换。例如,我想通过立即设置background-color: yellow;
来突出显示某些元素,并通过单向过渡将其设置回background-color: white;
。
我尝试使用 JavaScript 来实现这一点,如下所示:
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>
问题是,如果我一次切换一次类,过渡效果很好。
// This works fine.
highlightToggleBtn.addEventListener("click", () => {
bodyClassList.toggle("highlight");
});
但是,对于原始目标,我想突出显示该元素,所以我将添加/删除到同一元素只是想看到单向过渡,它失败了。
highlightBtn.addEventListener("click", () => {
bodyClassList.add("highlight");
bodyClassList.remove("highlight");
/*
This doesn't work, either.
bodyClassList.toggle("highlight");
bodyClassList.toggle("highlight");
*/
});
但是,如果我使用延迟为 0 毫秒的setTimeout
,则结果是理想的。
highlightTimeoutBtn.addEventListener("click", () => {
bodyClassList.add("highlight");
setTimeout(() => {bodyClassList.remove("highlight");});
/*
This works, too.
bodyClassList.toggle("highlight");
setTimeout(() => {bodyClassList.toggle("highlight");});
*/
});
为什么第二种方法不起作用?把removeClass
放进去setTimeout
是最好的解决方案吗?我还尝试在我的身体过渡 CSS 中延迟,例如:transition: background-color 1s ease 1ms;
,但它也不起作用。
更改类后重排/重绘,否则浏览器将优化并直接跳到最终状态(基本上,浏览器不会更新 UI,直到所有函数都完成运行)。您可以使用 setTimeout
,但如果您觉得它太臃肿(并且 setTimeout 实际上并不总是可靠的),您可以通过访问元素的 .offsetHeight
属性来触发/强制回流:
element.classList.add('highlight')
element.offsetHeight
element.classList.remove('highlight')
我建议您阅读本文,因为它将帮助您了解更多并避免将来出现陷阱:http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/
还有其他强制回流的方法:https://gist.github.com/paulirish/5d52fb081b3570c81e3a