我想以单向方式进行 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");
*/
});
但是,如果我使用延迟为 0 毫秒的 setTimeout
,结果是理想的。
highlightTimeoutBtn.addEventListener("click", () => {
bodyClassList.add("highlight");
setTimeout(() => {bodyClassList.remove("highlight");});
/*
This works, too.
bodyClassList.toggle("highlight");
setTimeout(() => {bodyClassList.toggle("highlight");});
*/
});
为什么第二种方法不行?将 removeClass
放在 setTimeout
中是最好的解决方案吗?我还尝试在 body 的过渡 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
关于javascript - 当按顺序添加/删除类时,由 JavaScript 控制的 CSS3 单向转换不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36834526/