【问题标题】:What purpose does void element.offsetWidth serve?void element.offsetWidth 有什么作用?
【发布时间】:2021-09-02 20:02:09
【问题描述】:

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

example-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>

【问题讨论】:

    标签: javascript html css css-animations


    【解决方案1】:

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

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

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

    这行额外的代码正在做的是要求浏览器为您提供有关 dom 的信息。但是为了知道 offsetWidth 是什么,浏览器必须放弃批量更改的计划,现在就执行页面的重排。当前状态没有运行动画类,这是一个变化,因此动画被重置。稍后,当函数完成时,它会再次执行计算,并看到您已经进行了另一项更改,相对于它为您提供 offsetWidth 的时间,所以它也应用了。

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

    另一种方法是立即删除该类,然后稍后再添加该类,如下所示:

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

    【讨论】:

      猜你喜欢
      • 2013-01-25
      • 2012-12-12
      • 2012-12-09
      • 1970-01-01
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多