总是讲回流重绘,它的应用场景是什么?

案例

点击开始按钮,让div执行动画。一个简单的demo来试一下回流重绘应用场景。
总是讲回流重绘,它的应用场景是什么?_第1张图片

开始简单的布局

<div class="box">div>
<button id="btn">开始button>
html,
 body {
   height: 100%;
 }

 body {
   display: flex;
   justify-content: center;
   align-items: center;
   flex-direction: column;
   gap: 20px;
 }

 .box {
   width: 100px;
   height: 100px;
   background: #badc58;
 }

点击实现动画

这里的动画就用css实现,通过给div加上一个类名,这个类名里面包含了动画;现在只需要点击按钮给div加类名即可

 .box.animate {
   animation: jump 500ms ease-in-out;
 }

 @keyframes jump {
   0%,
   100% {
     transform: translateY(0);
   }

   50% {
     transform: translateY(-20px);
   }
 }
 const btn = document.querySelector("#btn");
 const box = document.querySelector(".box");

 btn.addEventListener("click", () => {
   box.classList.add("animate");
 });

回流的使用

动画可以实现,但是只能实现一次,因为第一次过后类名就会保留下来,再次点击也不会有效果。
那我们就可以想到,每次点击的时候先把类名干掉,再重新加上去.

btn.addEventListener("click", () => {
  box.classList.remove("animate");
  box.classList.add("animate");
});

发现和之前一样,还是只有第一次可以动起来;这是为什么呢?因为我们删除和添加操作一瞬间完成的。浏览器不会感知到页面的变化,自然不会重绘;那我只能让它强制重绘,给它补一个回流(回流必重绘)。

btn.addEventListener("click", () => {
  box.classList.remove("animate");
  // 让浏览器强制回流,哪些操作可以让浏览器回流,可以看下面的介绍。
  void box.offsetWidth;
  box.classList.add("animate");
});

哪些操作会执行回流呢

  • DOM的增删行为
    比如你要删除某个节点,给某个父元素增加子元素,这类操作都会引起回流。如果要加多个子元素,最好使用documentfragment。

  • 几何属性的变化
    比如元素宽高变了,border变了,字体大小变了,这种直接会引起页面布局变化的操作也会引起回流。如果你要改变多个属性,最好将这些属性定义在一个class中,直接修改class名,这样只用引起一次回流。

  • 元素位置的变化
    修改一个元素的左右margin,padding之类的操作,所以在做元素位移的动画,不要更改margin之类的属性,使用定位脱离文档流后改变位置会更好。

  • 获取元素的偏移量属性
    例如获取一个元素的scrollTop、scrollLeft、scrollWidth、offsetTop、offsetLeft、offsetWidth、offsetHeight之类的属性,浏览器为了保证值的正确也会回流取得最新的值,所以如果你要多次操作,最好取完做个缓存。

  • 页面初次渲染
    这样的回流无法避免

  • 浏览器窗口尺寸改变
    resize事件发生也会引起回流。

你可能感兴趣的:(#,CSS学习,HTML-CSS学习,css3,css,javascript)