index.html:如何制作一个全屏的内容切换页面?

作者:袖梨 2026-06-27
全屏切换页面的核心是CSS viewport与JavaScript事件控制结合,需用100vh/min-height:100dvh、overflow:hidden、scroll-behavior:smooth,并配合scrollIntoView精准锚定、preventDefault阻止默认滚动、IntersectionObserver检测激活页及规避移动端兼容性问题。

全屏切换页面的核心是 CSS viewport + JavaScript 事件控制

直接用 height: 100vh 不够,必须配合 overflow: hiddenscroll-behavior: smooth(可选),否则滚动会“漏出”或跳变。移动端尤其要注意 vh 在 Safari 中的缩放 bug——页面放大时 100vh 会小于可视区,推荐用 min-height: 100dvh(现代浏览器)或回退到 100vh

结构上建议用单层 <section> 平铺,每个 section 高度设为 100vh,不嵌套滚动容器;否则 touchmove 会被子元素拦截,导致滑动失效。

scrollIntoView 实现平滑切换(兼容性好、无依赖)

不用轮子,靠原生 API 就能完成。关键点不是“动画”,而是“精准锚定”和“阻止默认滚动干扰”:

  • section.scrollIntoView({ behavior: 'smooth', block: 'start' }) 是基础,但必须确保调用前页面没在滚动中,否则行为不可预测
  • 监听 wheeltouchmove 时,要 e.preventDefault(),否则系统滚动会和你的切换冲突
  • 移动端需同时监听 touchstart/touchend 记录位移差,仅靠 wheel 在 iOS 上不触发
  • 切换过程中禁用重复触发:加个 isScrolling 标志位,scrollend 事件(或 setTimeout 延迟)后重置

示例片段:

sections.forEach((sec, i) => {  sec.addEventListener('click', () => {    if (isScrolling) return;    isScrolling = true;    sec.scrollIntoView({ behavior: 'smooth' });  });});

IntersectionObserver 检测当前页并更新导航状态

单纯切换不够,用户需要知道“我在哪一页”。用 IntersectionObserver 监听各 section 的可见比例,比监听 scroll 事件更轻量、更准确:

立即学习“前端免费学习笔记(深入)”;

  • 阈值设为 [0.2, 0.5, 0.8],避免临界抖动;只在 entry.intersectionRatio > 0.5 时认为该页“激活”
  • 不要在 callback 里直接操作 DOM 样式,改用 class 切换,让 CSS 控制高亮
  • 注意首次加载时可能所有 section 都未进入视口(比如页面从底部打开),需手动触发一次 observer.takeRecords() 或初始化时检查 getBoundingClientRect()

常见错误:rootMargin: '0px' 导致首屏 section 在刚加载时 intersectionRatio = 0 —— 改成 '-1px''0px 0px -1px 0px' 可修复。

移动端滑动卡顿?重点查这三处

90% 的“滑不动”问题出在以下三个地方,而不是 JS 性能:

  • CSS 中写了 transform: translateZ(0)will-change: transform 却没配 backface-visibility: hidden,导致 iOS 渲染层撕裂
  • section 内有 inputvideoiframe,它们会劫持 touch 事件,需加 pointer-events: none(内容区域除外)
  • bodyhtml 上设置了 overscroll-behavior: contain,但没同步加到各 section 上,导致滑动到边界时整个页面晃动

真正难调的是 Safari 的 dvh 支持不一致和微信内置浏览器对 scroll-behavior 的部分忽略——这种时候老老实实用 window.scrollTo({ top: target.offsetTop }) + CSS @media (prefers-reduced-motion) 降级更稳。

相关文章

精彩推荐