如何实现 JS 中的 iOS 滚动穿透

在开发移动端应用时,特别是在 iOS 系统上,可能会遇到一个常见问题:当你在某个弹出框内滚动内容时,背景的滚动也会穿透到下面的内容。这种现象被称为“滚动穿透”。为了优化用户体验,我们需要实现滞止背景滚动的效果。

本篇文章将详细介绍如何在 JavaScript 中实现 iOS 滚动穿透的解决方案。文章包括了整体流程、每一步操作的详细代码以及必要的注释,同时配有序列图和流程图,让你能够清晰理解整个过程。

整体流程

以下是实现 iOS 滚动穿透的整体流程:

步骤 描述
1 识别触摸事件
2 防止事件冒泡
3 阻止背景滚动
4 恢复背景滚动

步骤详细说明

步骤 1:识别触摸事件

首先,我们需要在需要阻止滚动的元素上添加触摸事件监听器,以便开始处理用户的滚动行为。

const modal = document.querySelector('.modal');

// 监听 touchstart 事件
modal.addEventListener('touchstart', (e) => {
  // 可以在这里进行后续的逻辑处理
  console.log('Touch started on modal');
}, { passive: false });
  • 这段代码选择了一个模态框 .modal,并在其上添加了 touchstart 事件监听器。
  • 通过 { passive: false },我们能够告知浏览器我们计划阻止事件的默认行为。

步骤 2:防止事件冒泡

当在模态框内滚动内容时,我们需要阻止事件冒泡,以确保不影响背景内容。

modal.addEventListener('touchmove', (e) => {
  e.preventDefault(); // 阻止默认行为,防止背景滚动
  console.log('Touch moving on modal');
}, { passive: false });
  • e.preventDefault() 被调用,以阻止模态框外部的背景滚动。

步骤 3:阻止背景滚动

为了确保用户在模态框打开时,背景的滚动被完全禁用,我们可以在模态框打开时,全局禁用滚动。

function openModal() {
  modal.classList.add('open');
  document.body.style.overflow = 'hidden'; // 禁用背景滚动
  console.log('Modal opened and body scroll disabled');
}

function closeModal() {
  modal.classList.remove('open');
  document.body.style.overflow = ''; // 恢复背景滚动
  console.log('Modal closed and body scroll enabled');
}
  • openModal 函数在模态框打开时被调用,禁用了 body 的滚动。
  • closeModal 函数在模态框关闭时被调用,以恢复 body 的滚动。

步骤 4:恢复背景滚动

最后,我们需要确保在模态框关闭后,背景的滚动恢复正常。上面已经在 closeModal 中考虑到了这个部分。

完整的代码示例

整合以上所有步骤,我们将拥有以下完整的实现代码:

const modal = document.querySelector('.modal');

modal.addEventListener('touchstart', (e) => {
  console.log('Touch started on modal');
}, { passive: false });

modal.addEventListener('touchmove', (e) => {
  e.preventDefault();
  console.log('Touch moving on modal');
}, { passive: false });

function openModal() {
  modal.classList.add('open');
  document.body.style.overflow = 'hidden'; // 禁用背景滚动
  console.log('Modal opened and body scroll disabled');
}

function closeModal() {
  modal.classList.remove('open');
  document.body.style.overflow = ''; // 恢复背景滚动
  console.log('Modal closed and body scroll enabled');
}

序列图

以下是用户操作和系统反应的序列图:

sequenceDiagram
    participant User
    participant App
    User->>App: Open Modal
    App->>Modal: Add 'open' class
    App->>Body: Set overflow to hidden
    User->>Modal: Scroll inside Modal
    App->>Modal: Prevent background scroll
    User->>App: Close Modal
    App->>Modal: Remove 'open' class
    App->>Body: Restore overflow

流程图

以下是整体流程的流程图:

flowchart TD
    A[识别触摸事件] --> B[防止事件冒泡]
    B --> C[阻止背景滚动]
    C --> D[恢复背景滚动]

结尾

通过以上步骤,我们成功地在 JavaScript 中实现了 iOS 的滚动穿透处理。这涉及到限制触摸事件的传播、管理模态框的开关以及动态调整页面的滚动行为。确保用户在使用模态框时获得良好的体验可以让你的应用更加友好。希望本文能帮助你顺利实现这一功能,提升你的开发技能!