猿问

void element.offsetWidth 的用途是什么?

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>


MM们
浏览 68回答 1
1回答

泛舟湖上清波郎朗

当您对 dom 进行更改(例如 )时classList.remove('anim'),这可能会导致页面发生一系列更改。渲染这些更改可能会很昂贵,而且由于您连续更改多个内容的情况很常见,因此浏览器会尝试批量处理累积的更改,并且仅在您正在执行的操作结束时执行计算。因此,如果那条奇怪的线不存在,那么将会发生以下情况:您删除该类。浏览器注意到了这一点,但尚未重绘屏幕您添加班级。浏览器注意到了这一点,但尚未重绘屏幕您的函数完成,浏览器决定进行必要的计算以使页面匹配您所要求的内容......但没有任何改变!您已将页面恢复到单击处理程序开始之前的相同状态。由于没有任何改变,所以显示保持不变;没有动画运行。这行额外的代码的作用是要求浏览器提供有关 dom 的信息。但为了知道 offsetWidth 是多少,浏览器必须放弃批量更改的计划并立即执行页面的回流。当前状态没有运行动画类,这是一个更改,因此动画会重置。稍后,当该函数完成时,它会再次执行计算,并发现您已经进行了另一项更改(相对于它为您提供 offsetWidth 时的更改),因此它也应用了该更改。简而言之:您迫使浏览器做额外的工作,而在这种情况下,这恰好是可取的。在大多数情况下,强迫浏览器做额外的工作是一件坏事。大多数时候,您希望避免以这种方式查询 dom,因为它会降低性能。让它发挥作用的另一种方法是现在删除该类,然后稍后添加该类,如下所示:element.addEventListener("click",&nbsp;function(e){ &nbsp;&nbsp;element.classList.remove("anim");&nbsp;&nbsp;setTimeout(()&nbsp;=>&nbsp;element.classList.add("anim"),&nbsp;0); },&nbsp;false);
随时随地看视频慕课网APP

相关分类

Html5
我要回答