为了账号安全,请及时绑定邮箱和手机立即绑定

void element.offsetWidth 的用途是什么?

void element.offsetWidth 的用途是什么?

MM们 2023-09-11 15:05:24
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);


查看完整回答
反对 回复 2023-09-11
  • 1 回答
  • 0 关注
  • 67 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信