void element.offsetWidth;是一行奇怪的代码,它似乎什么也不做,但却是 CSS 动画工作所必需的。这条线有什么作用以及为什么需要它?如果整行被注释掉,动画会发生一次但不会重复。void(如果删除它仍然有效。)完整的代码/演示在这里;我尝试复制以下相关摘录:脚本.js:beatIndicator = document.getElementById("beatIndicator"),...// Happens every time a beat starts:beatIndicator.classList.remove("anim");void beatIndicator.offsetWidth; // Why is this line needed?beatIndicator.classList.add("anim");示例-高级.html<span style="display: none;" id="beatIndicator" class="pulse"></span><style>.pulse { width: 40px; height: 40px; border-radius: 50%; background: #f44336; z-index: 3; left: -18px; display: inline-block; vertical-align: middle; margin-left: 10px; } @keyframes pulse-anim { from { box-shadow: rgba(244, 67, 54, 1) 0px 0px 0px 0px; } to { box-shadow: rgba(244, 67, 54, 0) 0px 0px 0px 14px; } } .pulse.anim { animation: pulse-anim; } </style>
1 回答
泛舟湖上清波郎朗
TA贡献1818条经验 获得超3个赞
当您对 dom 进行更改(例如 )时classList.remove('anim')
,这可能会导致页面发生一系列更改。渲染这些更改可能会很昂贵,而且由于您连续更改多个内容的情况很常见,因此浏览器会尝试批量处理累积的更改,并且仅在您正在执行的操作结束时执行计算。
因此,如果那条奇怪的线不存在,那么将会发生以下情况:
您删除该类。浏览器注意到了这一点,但尚未重绘屏幕
您添加班级。浏览器注意到了这一点,但尚未重绘屏幕
您的函数完成,浏览器决定进行必要的计算以使页面匹配您所要求的内容......但没有任何改变!您已将页面恢复到单击处理程序开始之前的相同状态。由于没有任何改变,所以显示保持不变;没有动画运行。
这行额外的代码的作用是要求浏览器提供有关 dom 的信息。但为了知道 offsetWidth 是多少,浏览器必须放弃批量更改的计划并立即执行页面的回流。当前状态没有运行动画类,这是一个更改,因此动画会重置。稍后,当该函数完成时,它会再次执行计算,并发现您已经进行了另一项更改(相对于它为您提供 offsetWidth 时的更改),因此它也应用了该更改。
简而言之:您迫使浏览器做额外的工作,而在这种情况下,这恰好是可取的。在大多数情况下,强迫浏览器做额外的工作是一件坏事。大多数时候,您希望避免以这种方式查询 dom,因为它会降低性能。
让它发挥作用的另一种方法是现在删除该类,然后稍后添加该类,如下所示:
element.addEventListener("click", function(e){ element.classList.remove("anim"); setTimeout(() => element.classList.add("anim"), 0); }, false);
- 1 回答
- 0 关注
- 67 浏览
添加回答
举报
0/150
提交
取消