IntersectionObserver 和 transform:转换不可预知的行为

IntersectionObserver and transform: translate unpredictable behaviour

提问人:Ameen Shamsan 提问时间:9/24/2023 最后编辑:Ameen Shamsan 更新时间:9/24/2023 访问量:31

问:

我有以下代码,我试图通过将 div 从 转换为 来实现它们与 相交后显示 。然而,它会产生奇怪和非理性的行为。使用相同的配置,我只是用 替换了 ,并且按预期顺利运行。IntersectionObserverdivroot viewport400%0transform: translateXopacityIntersectionObserver

const allDivs = document.querySelectorAll(".content");

// Observer Options
const obsOptions = {
  root: null,
  threshold: 1,
};

// Observer Callback
const obsCallback = function (entries, observer) {
  for (const entry of entries) {
    if (entry.isIntersecting && entry.intersectionRatio >= 1) {
      entry.target.classList.add("show");
    } else {
      entry.target.classList.remove("show");
    }
  }

};

// Creating Observer
const theObserver = new IntersectionObserver(obsCallback, obsOptions);


allDivs.forEach((div) => {
  theObserver.observe(div);
});
body {
  height: 3000px;
  /* height: 150vh; */
  display: flex;
  flex-direction: column;
  align-items: center;
}

div.container {
  width: 500px;
  background-color: antiquewhite;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

div.container .content {
  background-color: chocolate;
  width: 300px;
  height: 100px;
  font-size: 3rem;
  display: flex;
  justify-content: center;
  align-items: center;
  transform: translateX(400%);
  transition: transform 0.3s ease-in;
}

div.container .content.show {
  transform: translateX(0);
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Scroll Animation</title>
</head>
<body>
    
  
        <h1>Scroll to see animation</h1>
        <div class="container">
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">4th - Content</div>
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">4th - Content</div>
           </div>

    <script src="script.js"></script>
    
</body>
</html>

因此,IntersectionObserver 和转换是否不能协同工作,或者我遗漏了什么?谢谢您的合作

javascript css css-transforms

评论


答:

2赞 InspectorGadget 9/24/2023 #1

这部分会导致类不断添加和删除,因此动画没有时间显示。show

if (entry.isIntersecting && entry.intersectionRatio >= 1) {
    entry.target.classList.add("show");
} else {
    entry.target.classList.remove("show");
}

所以我把它改成只添加,不删除:

if (entry.isIntersecting && entry.intersectionRatio >= 1) {
    entry.target.classList.add("show");
}

下面是完全有效的示例:

const allDivs = document.querySelectorAll(".content");

// Observer Options
const obsOptions = {
  root: null,
  threshold: 1,
};


// Observer Callback
const obsCallback = function (entries, observer) {
  for (const entry of entries) {   
    if (entry.isIntersecting && entry.intersectionRatio >= 1) {
      entry.target.classList.add("show");
    }
  }
};

// Creating Observer
const theObserver = new IntersectionObserver(obsCallback, obsOptions);


allDivs.forEach((div) => {
  theObserver.observe(div);
});
body {
  height: 3000px;
  /* height: 150vh; */
  display: flex;
  flex-direction: column;
  align-items: center;
}

.container {
  width: 500px;
  background-color: antiquewhite;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.content {
  background-color: chocolate;
  width: 300px;
  height: 100px;
  font-size: 3rem;
  display: flex;
  justify-content: center;
  align-items: center;
  opacity: 0;
}

.show {
  animation-duration: 0.4s;
  animation-name: anim;
  animation-iteration-count: 1;
  opacity: 1;
}

@keyframes anim {
  from {
    transform: translateX(400%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Scroll Animation</title>
</head>
<body>
    
  
        <h1>Scroll to see animation</h1>
        <div class="container">
            <div class="a"></div>
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">4th - Content</div>
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">Content</div>
            <div class="content">4th - Content</div>
           </div>

    <script src="script.js"></script>
    
</body>
</html>