我想以单向方式进行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");
});
但是,对于原始目标,我想要突出显示该元素,所以我把add / remove添加到同一个元素只是想看单向转换,它失败了。
highlightBtn.addEventListener("click", () => {
bodyClassList.add("highlight");
bodyClassList.remove("highlight");
/*
This doesn't work, either.
bodyClassList.toggle("highlight");
bodyClassList.toggle("highlight");
*/
});
但是,如果我使用setTimeout
延迟时间为0 ms,则结果是理想的。
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;
,但它也不起作用。
答案 0 :(得分:1)
您需要在更改类之后重排/重绘,否则浏览器将优化并直接跳到结束状态(基本上,浏览器不会更新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