首页 > 其他分享 >移动端滚动穿透是什么原因?有哪些解决方案?

移动端滚动穿透是什么原因?有哪些解决方案?

时间:2024-12-01 09:02:33浏览次数:9  
标签:body 滚动 解决方案 穿透 modal 弹窗 页面

移动端滚动穿透是指在移动端页面中,当一个弹窗或遮罩层弹出后,在弹窗上滑动,底层页面也跟着滚动的问题。这会影响用户体验,让人感觉操作混乱。

造成滚动穿透的原因主要有以下几种:

  • touchmove 事件冒泡: 当在弹窗上进行触摸滑动操作时,touchmove 事件会默认冒泡到底层页面,触发底层页面的滚动。
  • 惯性滚动: 即使阻止了 touchmove 的默认行为,由于惯性滚动,底层页面仍然可能发生滚动。
  • 某些特定 CSS 属性: 例如 -webkit-overflow-scrolling: touch; 虽然可以提升 iOS 上的滚动性能,但在某些情况下也会导致滚动穿透。

以下是一些常见的解决方案,并分析了它们的优缺点:

1. 阻止冒泡:

  • 原理: 在弹窗的 touchmove 事件处理函数中调用 event.preventDefault()event.stopPropagation() 阻止事件的默认行为和冒泡。

  • 代码示例:

const modal = document.getElementById('modal');
modal.addEventListener('touchmove', function(event) {
  event.preventDefault(); // 阻止默认行为,推荐使用
  // event.stopPropagation(); // 阻止冒泡,可能影响弹窗内部的滚动
});
  • 优点: 简单易用。
  • 缺点: 如果弹窗本身需要滚动,这种方法会阻止弹窗内部的滚动。

2. 锁定 body 的 overflow 属性:

  • 原理: 在弹窗弹出时,将 bodyoverflow 属性设置为 hidden,阻止底层页面的滚动。在弹窗关闭时,恢复 bodyoverflow 属性。

  • 代码示例:

const body = document.body;
const modal = document.getElementById('modal');

function openModal() {
  body.style.overflow = 'hidden';
  modal.style.display = 'block';
}

function closeModal() {
  body.style.overflow = 'auto'; // 或初始值
  modal.style.display = 'none';
}
  • 优点: 兼容性好,实现简单。
  • 缺点: 如果页面原本就有滚动条,隐藏滚动条可能会导致页面抖动或布局错乱。 此外,如果页面结构复杂,例如有多个嵌套的滚动区域,这种方法可能失效。

3. 使用 position: fixed 定位弹窗:

  • 原理: 使用 position: fixed 定位弹窗,使其脱离文档流,不会影响底层页面的滚动。

  • 代码示例: 确保弹窗的 CSS 中包含 position: fixed;

  • 优点: 通常情况下可以有效防止滚动穿透。

  • 缺点: 需要配合其他样式进行调整,例如设置 topleftwidthheight 等属性,确保弹窗的正确显示位置和大小。

4. JavaScript 动态计算滚动位置:

  • 原理: 在弹窗弹出时,记录当前页面的滚动位置。在 touchmove 事件中,强制将页面滚动位置设置为记录的值,阻止页面滚动。

  • 代码示例: 较为复杂,需要根据具体场景进行调整。

  • 优点: 可以精细控制滚动行为。

  • 缺点: 实现较为复杂,可能会影响性能。

5. CSS 属性 overscroll-behavior:

  • 原理: 使用 CSS 属性 overscroll-behavior: contain; 可以阻止滚动链,从而防止滚动穿透。

  • 代码示例:

.modal {
  overscroll-behavior: contain;
}
  • 优点: 简单易用,兼容性较好 (iOS Safari 15+ 和大部分现代浏览器)。
  • 缺点: 对于一些老旧浏览器不兼容。

最佳实践建议:

  • 优先考虑使用 position: fixedoverscroll-behavior: contain,它们通常能有效解决滚动穿透问题,并且实现简单。
  • 如果弹窗本身需要滚动,避免使用阻止冒泡的方法。
  • 对于复杂的页面结构,可能需要结合多种方法来解决滚动穿透问题。
  • 测试不同机型和浏览器,确保兼容性。

选择哪种方案取决于项目的具体情况和需求。 建议根据实际情况进行测试和选择最合适的解决方案。

标签:body,滚动,解决方案,穿透,modal,弹窗,页面
From: https://www.cnblogs.com/ai888/p/18579320

相关文章

  • 中睿智能:领航前行,2024智能仓储物流行业解决方案合作论坛盛启
    11月28日,由东莞市工业和信息化局指导,广东中睿智能科技有限公司(以下简称“中睿智能仓储”)主办的“仓储新动能智造新未来——2024智能仓储物流行业解决方案合作论坛”在东莞东城新发兴创新工场盛大举行。此次论坛汇聚了来自智能仓储物流行业的专家学者、企业精英和技术骨干,共......
  • 使用Mybatis-Plus时遇到的报错问题及解决方案
    创建Maven项目后,一个个手动添加spring-boot和mybatis-plus依赖冲突问题解决方案:找一个现成的pom.xml文件替换后重新加载(以下提供java8,对应的spring-boot,mybatis-plus依赖)<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"......
  • 开发者必看:如何在IDEA中使用内网穿透工具实现远程连接本地Mysql数据库
    个人名片......
  • 宝塔安装后网址打不开的解决方案及排查思路
    排查思路初步检查网络连接:确认服务器网络是否正常。面板状态:检查宝塔面板是否正常运行。配置检查网站配置:检查网站的域名绑定、端口设置、SSL证书等配置。防火墙设置:确保80和443端口已开放。端口占用:检查80和443端口是否被其他服务占用。日志分析访问日志:查看......
  • 怎么让table的thead 不动,tbody出现滚动条呢?
    要让table的thead固定不动,tbody出现滚动条,你需要使用CSS来控制表格的布局和样式。以下是一种常见且有效的方法:<!DOCTYPEhtml><html><head><style>table{width:100%;table-layout:fixed;/*重要:固定表格布局*/border-collapse:collapse;/*可选:合并表......
  • 如何设置背景图片不随着文本内容的滚动而滚动?
    要设置背景图片不随着文本内容滚动,也就是使其固定在视口上,可以使用CSS的background-attachment:fixed;属性。以下是如何在不同情况下应用此属性的方法:1.应用于body元素:这将使背景图片固定在整个页面上,即使页面内容很长,背景图片也不会滚动。body{background-image......
  • OpenVZ 9.0 - 基于容器的 Linux 开源虚拟化解决方案
    OpenVZ9.0-基于容器的Linux开源虚拟化解决方案Opensourcecontainer-basedvirtualizationforLinux请访问原文链接:https://sysin.org/blog/openvz-9/查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgPoweredbyVirtuozzoOpenVZ允许多个安全、隔离的Linu......
  • 为什么云桌面是远程工作的终极解决方案
    云桌面可以解决什么问题?对于打工人,远程办公有利有弊,虽然不用到公司上班可以节省大家的通勤时间,但是不少公司缺乏远程办公经验,很容易遇到一些难题,不但会对工作效率产生影响,甚至会耽误项目交付。对于有制图、3D建模、渲染需求的工作者,家中电脑配置老旧可能无法满足运行专业软件......
  • VMware VeloCloud SD-WAN 5.0 下载 - 领先的 SD-WAN 解决方案
    VMwareSD-WAN5.0-领先的SD-WAN解决方案请访问原文链接:https://sysin.org/blog/vmware-sd-wan-5/查看最新版。原创作品,转载请保留出处。作者主页:sysin.org产品概述软件定义的WAN(SD-WAN)SD-WAN的功能特性简化的SD-WAN了解软件定义的WAN(SD-WAN)的概......
  • uniapp学习如何监听页面滚动
    uniapp提供了一个原生的事件.onPageScroll(){}去监听页面滚动的时候出发提供了一个让页面主动去滚动的事件uni.pageScrollTop({duration:0,scrollTop:100px}).提供了一个页面下拉重新刷新的原生事件.onPullDoenRefresh(){}提供了一个页面下拉置底的原生事件.通常用来去获取新的......