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

窗口无实际滚动时,如何监听滚动操作并实现透明度动画?

问题描述

网站所有section区块均设置为100vw/100vh尺寸,希望在用户尝试向上或向下滚动时实现区块的透明度过渡动画,但由于窗口无实际滚动内容,scroll事件无法触发。

相关代码示例:

.section {
  width: 100vw;
  height: 100vh;
  opacity: 0;
  transition: opacity 0.5s;
}

.section.active {
  opacity: 1;
}
<div class="section active">Some stuff here...</div>
<div class="section">Some stuff here...</div>
window.addEventListener("scroll", () => {
  console.log("never fires")
})

请问该需求是否可实现?若不可行,有哪些替代方案?


解决方案

这个需求完全可以实现,核心是放弃监听scroll事件,转而捕捉用户的滚动操作意图(如鼠标滚轮、触摸滑动),配合逻辑切换active类来完成透明度过渡。

具体实现方案

1. 监听鼠标滚轮事件

通过wheel事件捕捉桌面端用户的滚动操作,根据滚动方向切换激活的section:

let currentSectionIndex = 0;
const sections = document.querySelectorAll('.section');
let isAnimating = false; // 防止滚动触发过于频繁,避免动画冲突

window.addEventListener('wheel', (e) => {
  if (isAnimating) return;
  isAnimating = true;

  // 根据滚轮方向判断切换方向
  const direction = e.deltaY > 0 ? 1 : -1;
  const nextIndex = currentSectionIndex + direction;

  // 边界校验,防止索引越界
  if (nextIndex < 0 || nextIndex >= sections.length) {
    isAnimating = false;
    return;
  }

  // 切换active类实现透明度过渡
  sections[currentSectionIndex].classList.remove('active');
  sections[nextIndex].classList.add('active');
  currentSectionIndex = nextIndex;

  // 动画结束后解除锁定,时长对应CSS中transition的设置
  setTimeout(() => {
    isAnimating = false;
  }, 500);
});

2. 监听触摸滑动事件

针对移动端用户,通过touchstart和touchmove事件判断滑动方向:

let startY;
let currentSectionIndex = 0;
const sections = document.querySelectorAll('.section');
let isAnimating = false;

window.addEventListener('touchstart', (e) => {
  startY = e.touches[0].clientY;
});

window.addEventListener('touchmove', (e) => {
  if (isAnimating) return;
  const endY = e.touches[0].clientY;
  const diffY = endY - startY;

  // 设置阈值避免轻微触摸误触发
  if (Math.abs(diffY) < 50) return;
  isAnimating = true;

  const direction = diffY < 0 ? 1 : -1;
  const nextIndex = currentSectionIndex + direction;

  if (nextIndex < 0 || nextIndex >= sections.length) {
    isAnimating = false;
    return;
  }

  sections[currentSectionIndex].classList.remove('active');
  sections[nextIndex].classList.add('active');
  currentSectionIndex = nextIndex;

  setTimeout(() => {
    isAnimating = false;
  }, 500);
});

优化建议

  • 给section添加position: fixed,确保每个区块都固定占满视口,避免布局偏移;
  • 可结合transform属性实现位移+透明度的组合动画,提升视觉流畅度;
  • 增加键盘方向键监听(keydown事件),支持键盘操作切换区块,提升页面可访问性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:33:22