You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Intersection Observer实现滚动图文渐显功能遇阻求助

滚动渐显效果失效问题修复

问题症状

尝试实现滚动时文本和图片渐显效果,将元素初始opacity设为0,但滚动时元素始终透明,未触发opacity:1的切换,预期通过IntersectionObserver给.hidden元素添加.show类来显示内容。

问题根源

  1. JavaScript执行时机错误:脚本放在<head>中,DOM尚未完成渲染,无法获取到.hidden元素,导致Observer没有绑定到目标元素上。
  2. IntersectionObserver监听对象错误:页面滚动容器是.container(设置了overflow-y: auto),但默认的Observer监听的是浏览器视口,而非这个滚动容器,所以元素进入容器可视区域时不会触发回调。
  3. 缺少过渡动画(可选):未设置opacity的过渡效果,即使触发切换也会显得生硬。
  4. CSS拼写错误:.logo的right属性值写成了20spx,应为20px。

修复方案

1. 调整脚本加载位置

将<script>标签移至</body>闭合标签前,确保DOM渲染完成后再执行脚本。

2. 配置Observer监听滚动容器

创建Observer时指定root为.container,并设置合适的rootMargin让元素提前触发显示。

3. 添加过渡动画

给.hidden类添加transition属性,实现平滑的渐显效果。

4. 修正CSS拼写错误

将.logo的right:20spx改为right:20px。

修改后的完整代码

HTML

<!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">
    <link href="https://fonts.googleapis.com/css2?family=Nunito&display=swap" rel="stylesheet">
    <title>Discover</title>
</head>
<body>
<div class="container">
  <header>
    <img src="images/discover.jpg" alt="Not Loading" width="1470px" height="800px" class="background">
    <img src="images/logo.png" alt="Not Loading" class="logo" width="400px" height="75px">
    <div class="title">DISCOVER</div>
    <div class="subText">Find Your Dream House From The Relaxation Of Your Couch</div>
    <a href="#text">
      <div class="learnMore">
        <h3>Learn More</h3>
      </div>
    </a>
  </header>
  <section class="bellow">
   
    <div class="UniqueStyle">
    <div class="UniqueStyleText">    
        <h2 class="hidden">Unique Style</h2>
        <p class="hidden">这里可以添加具体文本内容</p>
    </div>
    <img src="image.jpg" alt="Not Loading" class="hidden">
   </div>

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

CSS

body {
    margin: 0;
    padding: 0;
    height: 1000vh;
}
  
a {
    text-decoration: none; 
}
  
section {
    font-size: 2rem;
    background-color: #333;
    padding: 40px;
    color: blueviolet;
}
  
.container {
    height: 100vh;
    overflow-y: auto;
    overflow-x: hidden;
    perspective: 10px;
    scroll-behavior: smooth;
}
  
header {
    position: relative;
    height: 100%;
    transform-style: preserve-3d;
    z-index: -1;
}
  
.background {
    position: absolute;
    height: 100%;
    width: 100%;
    object-fit: cover;
    z-index: -1;
    transform: translateZ(-10px) scale(2);
    filter: brightness(70%);
}
  
.logo {
    position: relative;
    right: 20px;
    top: 10px;
}
  
.title {
    z-index: 1;
    color: rgb(255, 255, 255);
    font-size: 120px;
    font-family: 'Nunito';
    position: relative;
    top: 15%;
    left: 10%;
    width: 400px;
    text-shadow: 0px 5px 5px rgba(0, 0, 0, 0.5);
}
  
.subText {
    z-index: 1;
    color: rgb(255, 255, 255);
    font-size: 25px;
    font-family: 'Nunito';
    position: relative;
    top: 13%;
    left: 10.5%;
    width: 700px;
    text-shadow: 0px 5px 5px rgba(0, 0, 0, 0.5);
}
  
.learnMore {
    background-color: white;
    width: 200px;
    height: 70px;
    display: flex;
    justify-content: center;
    align-items: center;
    text-decoration: none;
    position: relative;
    top: 17%;
    left: 10%;
    color: black;
    font-family: 'Nunito';
    box-shadow: 0px 5px 5px rgba(0, 0, 0, 0.5);
}
  
.learnMore:hover {
    background-color: gray;
}

.bellow {
    background-color: white;
}

.hidden {
    opacity: 0;
    transition: opacity 0.6s ease;
}

.show {
    opacity: 1;
}

JavaScript

const container = document.querySelector('.container');
const observer = new IntersectionObserver(entries => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            entry.target.classList.add('show')
        } else {
            entry.target.classList.remove('show')
        }
    }), {
        root: container,
        rootMargin: '0px 0px -50px 0px',
        threshold: 0.1
    }

const hiddenElements = document.querySelectorAll('.hidden')
hiddenElements.forEach(el => observer.observe(el))

内容的提问来源于stack exchange,提问作者Ethan Suwan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 02:53:11