滚动吸附一整屏方案

背景介绍

在当今的网页设计中,流畅的交互体验已成为用户评价产品品质的重要标准之一。其中,滚动吸附(Scroll Snapping) 作为一种常见的交互模式,通过将滚动内容自动对齐到预设的"吸附点"(如视口的顶部、底部或页面边界),为用户提供了一种精准、顺滑的浏览体验。这种技术被广泛应用于全屏轮播图、垂直/横向分页导航、长表单分步填写等场景,尤其在移动端触屏设备中,手指滑动后内容自动"吸附"到完整屏幕的特性,显著降低了用户的操作成本。

方法一:纯 CSS 实现

  • 使用 scroll-snap-type: y mandatory 启用垂直滚动吸附
  • 每个 section 设置 scroll-snap-align: start 对齐顶部
  • 隐藏滚动条提升美观度(可选)
xml 复制代码
<!DOCTYPE html>
<meta charset="UTF-8">
<head>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .container {
      height: 100vh;
      overflow-y: scroll;
      scroll-snap-type: y mandatory;
      scroll-behavior: smooth;
    }

    section {
      height: 100vh;
      scroll-snap-align: start;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 4em;
    }

    /* 可选:隐藏滚动条 */
    .container::-webkit-scrollbar {
      display: none;
    }
  </style>
</head>
<body>
<div class="container">
  <section style="background: #ff6b6b;">第一屏</section>
  <section style="background: #4ecdc4;">第二屏</section>
  <section style="background: #45b7d1;">第三屏</section>
  <section style="background: #96ceb4;">第四屏</section>
</div>
</body>
</html>

方法二:JavaScript 增强控制

  • 监听鼠标滚轮事件
  • 判断滚动方向(上/下)
  • 使用 scrollIntoView() 实现平滑滚动
  • 通过 flag 防止滚动冲突
xml 复制代码
<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .container {
      height: 100vh;
      overflow-y: scroll;
      scroll-behavior: smooth;
      -webkit-overflow-scrolling: touch; /* 移动端滚动优化 */
    }

    section {
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 4em;
      scroll-snap-align: start; /* 辅助平滑定位 */
    }
  </style>
</head>
<body>
<div class="container">
  <section style="background: #ff6b6b;">第一屏</section>
  <section style="background: #4ecdc4;">第二屏</section>
  <section style="background: #45b7d1;">第三屏</section>
  <section style="background: #96ceb4;">第四屏</section>
</div>

<script>
  let current = 0;
  let startY = 0;
  const sections = document.querySelectorAll('section');
  const container = document.querySelector('.container');
  let isScrolling = false;
  const threshold = 50; // 滑动阈值

  // 桌面端滚轮事件
  container.addEventListener('wheel', handleWheel, { passive: false });

  // 移动端触摸事件
  container.addEventListener('touchstart', handleTouchStart, { passive: false });
  container.addEventListener('touchend', handleTouchEnd, { passive: false });

  // 滚动事件
  function handleWheel(e) {
    e.preventDefault();
    if (isScrolling) return;

    const delta = Math.sign(e.deltaY);
    navigate(delta);
  }

  // 点击开始,如果是PC可以不要
  function handleTouchStart(e) {
    startY = e.touches[0].clientY;
  }

  // 点击结束,如果是PC可以不要
  function handleTouchEnd(e) {
    if (isScrolling) return;

    const endY = e.changedTouches[0].clientY;
    const delta = startY - endY; // 滑动距离

    if (Math.abs(delta) > threshold) {
      navigate(delta > 0 ? 1 : -1);
    }
  }

  // 计算滚动的最终位置
  function navigate(direction) {
    const newIndex = current + direction;

    if (newIndex >= 0 && newIndex < sections.length) {
      current = newIndex;
      scrollToSection();
    }
  }

  // 滑动
  function scrollToSection() {
    isScrolling = true;
    sections[current].scrollIntoView({
      behavior: 'smooth',
      block: 'start'
    });

    setTimeout(() => {
      isScrolling = false;
    }, 800);
  }

  // 禁用移动端双指缩放,如果是PC可以不要
  document.addEventListener('gesturestart', (e) => e.preventDefault());
  document.addEventListener('gesturechange', (e) => e.preventDefault());
</script>
</body>
</html>

总结

  • 推荐优先使用 CSS 方案,性能更好且代码更简洁
  • 可以通过修改 scroll-behavior 或动画时间调整滚动速度
  • 确保内容区块高度严格等于视口高度(100vh)

往期文章

唤起小程序呕血总结

h5跳转小程序指北

简单易上手!发布React + Vite + Storybook组件库

相关推荐
哀木9 分钟前
随笔之 react 接入 @xterm 的踩坑记录
前端
野生的程序媛24 分钟前
重生之我在学Vue--第13天 Vue 3 单元测试实战指南
前端·javascript·vue.js·单元测试
Aphasia31130 分钟前
简单介绍清除浮动解决高度塌陷的四种方法✍🏻
前端·css
Captaincc1 小时前
这款堪称编程界的“自动驾驶”利器,集开发、调试、提 PR、联调、部署于一体
前端·ai 编程
我是小七呦1 小时前
万字血书!TypeScript 完全指南
前端·typescript
simple丶2 小时前
Webpack 基础配置与懒加载
前端·架构
simple丶2 小时前
领域模型 模板引擎 dashboard应用列表及配置接口实现
前端·架构
冰夏之夜影2 小时前
【css酷炫效果】纯css实现液体按钮效果
前端·css·tensorflow
2 小时前
告别手写Codable!Swift宏库ZCMacro让序列化更轻松
前端
摘笑2 小时前
vite 机制
前端