Laggy/Glitchy CSS 动画仅适用于带有 Intersection Observer 的 Firefox

问题描述 投票:0回答:1

我正在利用 Intersection Observer API 在网站标题徽标未位于(或接近位于)背景图像上方时隐藏网站标题徽标。

在 Google Chrome、其他 chromium 浏览器和 Safari(至少是移动版本)上运行良好,但 CSS 动画在 Firefox 上播放非常缓慢,有时会延迟。事实上,有时它甚至不会触发,只是冻结。

当 CSS 动画不是由 Intersection Observer 添加类触发时,它可以正常显示。 (即:下例中的蓝色框默认具有淡入类,当您刷新页面并淡入时,动画可以流畅播放。)

我使用的是 Firefox 132.0.1(64 位)。 我已经要求其他人测试该网站,结果都是一样的。

这是我复制问题的示例页面,使用蓝色正方形作为标题徽标,红色矩形作为背景图像区域:

const header = document.getElementById("headerhide");
const region = document.querySelector(".header-background");

const observer = new IntersectionObserver(([entry]) => {
  header.classList.toggle("fade-out", !entry.isIntersecting);
  header.classList.toggle("fade-in", entry.isIntersecting);

}, {
  threshold: 0.2,
})
observer.observe(region)
.header-background {
  height: 500px;
  background-color: red;
}

.logo-container {
  position: fixed;
  top: 2%;
  left: 50%;
  transform: translate(-50%, 0);
  width: 80px;
  height: 80px;
  background-color: blue;
}

.logo.logo-container {
  position: absolute;
}

.container {
  height: 2000px;
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fade-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

.fade-in {
  opacity: 0;
  animation-name: fade-in;
  animation-duration: 0.4s;
  animation-timing-function: ease-out;
  animation-fill-mode: forwards;
}

.fade-out {
  opacity: 1;
  animation-name: fade-out;
  animation-duration: 0.2s;
  animation-timing-function: ease-out;
  animation-fill-mode: forwards;
}
<div class="container">
  <div class="headerhide" id="headerhide">
    <div class="logo-container">
      <div class="logo"></div>
    </div>
  </div>
  <div class="header-background" id="region"></div>
</div>

(编辑:也在 JSFiddle 上:https://jsfiddle.net/ob2t6wn3/3/

(CSS 和 js 通常位于不同的文件中,但为了示例,我将它们全部放在 html 中)

我的规格(尽管我在不同的设备上进行了测试,但问题仍然存在。)

操作系统:Windows 11 Home [64位] CPU:Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz 显卡:NVIDIA GeForce RTX 2070 内存:16GB 主板:微星国际有限公司MS-

我尝试过的事情:

  • 检查是否是 Firefox 设置问题,我排除了 about:config 和 Firefox Sync 中的privacy.fingerprintingProtection 标志,因为禁用其中一个或两个都无法解决问题。我想不出任何其他设置可能导致此问题。

  • will-change: opacity;
    添加到 CSS 类中,不起作用。

  • 添加了轻微的变换动画来触发硬件加速但不起作用,添加

    translateZ(0)
    也不起作用。

  • 在 JavaScript 函数中添加 debounce 不起作用 (虽然我不完全确定我是否做对了,但我 3 天前就开始学习 JavaScript 了。)

  • 使用 2 个观察者来切换不同的类,不起作用。

  • 尝试全新安装 Firefox(开发者版)。

  • 我尝试使用 CSS 过渡而不是关键帧,但这也没有解决问题。

javascript html css css-animations intersection-observer
1个回答
0
投票

我已经设法使用下面的代码使其在我这边工作。

我删除了定位值(

top
position: fixed
等)并将它们应用到正在观察的元素 -
#headerhide

我无法给你一个关于为什么它有效的彻底解释,但我假设它要么是因为

#headerhide
之前作为高度为 0 的空容器,因为它唯一的子元素有
position: fixed
,或者因为动画现在直接在可见元素上运行。

但以上只是猜测。

const header = document.getElementById("headerhide");
const region = document.querySelector(".header-background");

const observer = new IntersectionObserver(([entry]) => {
  header.classList.toggle("fade-out", !entry.isIntersecting);
  header.classList.toggle("fade-in", entry.isIntersecting);

}, {
  threshold: 0.2,
})
observer.observe(region)
.header-background {
  height: 500px;
  background-color: red;
}

#headerhide {
  width: 80px;
  height: 80px;
  z-index: 100;
  top: 2%;
  left: 50%;
  transform: translate(-50%, 0);
  position: fixed;
}

.logo-container {
  background-color: blue;
  height: 100%;
  width: 100%;
}

.logo.logo-container {
  position: absolute;
}

.container {
  height: 2000px;
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fade-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

.fade-in {
  opacity: 0;
  animation-name: fade-in;
  animation-duration: 0.4s;
  animation-timing-function: ease-out;
  animation-fill-mode: forwards;
}

.fade-out {
  opacity: 1;
  animation-name: fade-out;
  animation-duration: 0.2s;
  animation-timing-function: ease-out;
  animation-fill-mode: forwards;
}
<div class="container">
  <div class="headerhide" id="headerhide">
    <div class="logo-container">
      <div class="logo"></div>
    </div>
  </div>
  <div class="header-background" id="region"></div>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.