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

父容器中Div与下一个Div碰撞时实现淡出效果

我来帮你搞定这个sticky元素碰撞淡出的问题!你的思路方向完全没问题,大概率是碰撞检测的逻辑或者事件监听的细节没处理好,下面给你一套完整的可运行方案,一步一步来:

完整解决方案

1. HTML结构

先搭建基础的页面结构,给每个sticky元素统一类名,方便后续JS操作,再加个长内容区块让页面能滚动测试:

<div class="sticky-container">
  <div class="sticky-item">
    <img src="https://picsum.photos/300/200?random=1" alt="示例图片1">
    <p>第一个sticky元素</p>
  </div>
  <div class="sticky-item">
    <img src="https://picsum.photos/300/200?random=2" alt="示例图片2">
    <p>第二个sticky元素</p>
  </div>
  <div class="sticky-item">
    <img src="https://picsum.photos/300/200?random=3" alt="示例图片3">
    <p>第三个sticky元素</p>
  </div>
  <!-- 撑高页面,让滚动有意义 -->
  <div class="page-spacer"></div>
</div>

2. CSS样式

实现sticky定位、淡出过渡效果,同时优化元素的交互体验:

.sticky-container {
  max-width: 600px;
  margin: 0 auto;
  padding: 0 15px;
}

.sticky-item {
  position: sticky;
  top: 20px; /* 给sticky元素留顶部间距,避免贴死视口 */
  margin-bottom: 20px;
  padding: 15px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  /* 过渡效果要包含visibility,避免透明后仍占交互空间 */
  transition: opacity 0.5s ease, visibility 0.5s ease;
  opacity: 1;
  visibility: visible;
}

/* 你定义的淡出类 */
.sticky-item.is-gone {
  opacity: 0;
  visibility: hidden;
}

.page-spacer {
  height: 1500px; /* 足够长的滚动空间 */
}

img {
  width: 100%;
  height: auto;
  border-radius: 4px;
}

3. JavaScript逻辑

核心是滚动时检测元素碰撞,然后动态添加/移除淡出类:

const stickyItems = document.querySelectorAll('.sticky-item');

// 碰撞检测函数:判断下一个元素是否碰到当前元素
function isColliding(currentEl, nextEl) {
  const currentRect = currentEl.getBoundingClientRect();
  const nextRect = nextEl.getBoundingClientRect();
  
  // 当下一个元素的顶部 <= 当前元素的底部时,判定为碰撞
  // 可根据实际需求调整阈值,比如减去sticky的top间距
  return nextRect.top <= currentRect.bottom;
}

// 滚动处理函数
function handleScroll() {
  stickyItems.forEach((item, index) => {
    const nextItem = stickyItems[index + 1];
    if (!nextItem) return; // 最后一个元素没有下一个,直接跳过
    
    if (isColliding(item, nextItem)) {
      item.classList.add('is-gone');
    } else {
      // 滚动回去时恢复显示
      item.classList.remove('is-gone');
    }
  });
}

// 页面加载时先检查一次,避免初始状态异常
handleScroll();
// 添加滚动监听,优化性能用requestAnimationFrame包裹
window.addEventListener('scroll', () => {
  requestAnimationFrame(handleScroll);
});

关键细节说明

  • 碰撞检测:用getBoundingClientRect()获取元素相对于视口的实时位置,这是实现sticky元素碰撞检测的核心,因为sticky元素的位置会随滚动动态变化。
  • visibility属性:配合opacity一起过渡,是为了避免元素透明后仍占据页面空间、响应点击事件,让“淡出”的体验更完整。
  • 滚动优化:用requestAnimationFrame包裹处理函数,能减少滚动时的函数触发次数,提升页面性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:23:08