最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why does my IntersectionObserver trigger too often in a 3D transform container, but not in a 2D transform container

programmeradmin1浏览0评论

I'm playing around with IntersectionObserver in two different scrolling containers: one uses a 3D perspective transform, and the other uses a simpler 2D transform.

For the 3D container, the observer callback fires constantly while scrolling, even when the red box remains fully visible. Meanwhile, in the 2D container, it behaves how I'd expect—only firing noticeably when entering or leaving the viewport portion.

Below is my minimal example. If you open it and scroll each container separately, you’ll see the 3D container logs frequent small intersection changes, whereas the 2D container logs fewer. Is this normal with 3D transforms? Or am I misusing IntersectionObserver?

You can run the example(opening it on the full page so you can see it nicely)scroll and find the difference between these two.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>IntersectionObserver 3D vs 2D Transform</title>
  <style>
    pare-section {
      display: flex;
      gap: 20px;
      margin-bottom: 20px;
    }
    .container {
      width: 300px;
      height: 200px;
      border: 2px solid #333;
      overflow-y: scroll;
      position: relative;
    }
    .content {
      height: 600px;
      background: linear-gradient(to bottom, #eee, #ddd);
    }

    /* 3D container with perspective */
    .transform-container-3d {
      perspective: 500px;
    }
    .content3d {
      transform: rotateX(15deg);
      transform-origin: top center;
    }

    /* 2D container with a simple rotation */
    .transform-container-2d .content2d {
      transform: rotate(5deg);
      transform-origin: top center;
    }

    .target-box {
      width: 100px;
      height: 100px;
      margin: 50px auto;
      background-color: red;
    }

    .logs {
      font-family: monospace;
      white-space: pre;
      border: 1px solid #ccc;
      padding: 10px;
      height: 150px;
      width: 270px;
      overflow: auto;
    }

    h2 {
      margin: 0 0 10px;
    }
  </style>
</head>
<body>
  <h1>IntersectionObserver 3D vs 2D Transform Test</h1>

  <div class="compare-section">
    <div class="container transform-container-3d">
      <h2>3D Container</h2>
      <div class="content content3d">
        <div class="target-box" id="target3d"></div>
      </div>
    </div>
    <div class="container transform-container-2d">
      <h2>2D Container</h2>
      <div class="content content2d">
        <div class="target-box" id="target2d"></div>
      </div>
    </div>
  </div>

  <div class="compare-section">
    <div class="logs" id="log3d">3D Logs: </div>
    <div class="logs" id="log2d">2D Logs: </div>
  </div>


  <script>
    const target3d = document.getElementById('target3d');
    const log3d = document.getElementById('log3d');
    const target2d = document.getElementById('target2d');
    const log2d = document.getElementById('log2d');

    const observer3d = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        log3d.textContent += `ratio: ${entry.intersectionRatio.toFixed(2)}\n`;
      });
    }, {
      root: document.querySelector('.transform-container-3d'),
      threshold: [0, 0.25, 0.5, 0.75, 1]
    });

    const observer2d = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        log2d.textContent += `ratio: ${entry.intersectionRatio.toFixed(2)}\n`;
      });
    }, {
      root: document.querySelector('.transform-container-2d'),
      threshold: [0, 0.25, 0.5, 0.75, 1]
    });

    observer3d.observe(target3d);
    observer2d.observe(target2d);
  </script>
</body>
</html>

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论