gpt4 book ai didi

javascript - void element.offsetWidth 的用途是什么?

转载 作者:行者123 更新时间:2023-12-02 21:28:07 28 4
gpt4 key购买 nike

void element.offsetWidth; 是一行奇怪的代码,它似乎什么也没做,但却是 CSS 动画工作所必需的。这条线有什么作用以及为什么需要它?

如果整行被注释掉,动画会发生一次但不会重复。 (如果删除 void,它仍然有效。)

full code/demo住在这里;我尝试复制以下相关摘录:

script.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");

示例-advanced.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>

最佳答案

当您对 dom 进行更改(例如 classList.remove('anim'))时,可能会导致页面发生一系列更改。渲染这些更改的成本可能很高,而且由于您连续更改多个内容的情况很常见,因此浏览器会尝试批量处理累积的更改,并且仅在您正在执行的操作结束时执行计算。

因此,如果那条奇怪的线不存在,那么会发生以下情况:

  • 您删除了该类(class)。浏览器注意到了这一点,但尚未重绘屏幕
  • 您添加类(class)。浏览器注意到了这一点,但尚未重绘屏幕
  • 您的函数完成,浏览器决定进行必要的计算以使页面符合您所要求的内容...但没有任何变化!您已将页面恢复到单击处理程序开始之前的相同状态。由于没有任何改变,所以显示保持不变;没有动画运行。

这行额外的代码的作用是要求浏览器提供有关 dom 的信息。但为了知道 offsetWidth 是多少,浏览器必须放弃批量更改的计划并立即执行页面的回流。当前状态没有运行动画类,这是一个更改,因此动画会重置。稍后,当该函数完成时,它会再次执行计算,并发现您已经进行了另一项更改(相对于它为您提供 offsetWidth 时的情况),因此它也应用了该更改。

简而言之:您迫使浏览器做额外的工作,而在这种情况下,这恰好是可取的。在大多数情况下,强制浏览器做额外的工作是一件坏事。大多数时候您希望避免以这种方式查询 dom,因为它会降低性能。

使其发挥作用的另一种方法是立即删除该类,然后稍后添加该类,如下所示:

element.addEventListener("click", function(e){
element.classList.remove("anim");
setTimeout(() => element.classList.add("anim"), 0);
}, false);

关于javascript - void element.offsetWidth 的用途是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60686489/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com