iOS中pointer-events:none的iframe遮挡后方div滚动失效解决方案
iOS端被iframe遮挡的下层div无法滚动的解决方法
问题原因
iOS端全系列浏览器都基于WebKit内核,其连续滚动手势的命中测试逻辑和普通点击事件、其他平台逻辑存在差异:
普通点击事件可以正常穿透设置了pointer-events: none的iframe,但滚动手势属于连续交互事件,只要iframe的定位父容器是可命中状态(未设置pointer-events: none),手势就会被该覆盖层拦截,不会透传给下层的可滚动div。此前尝试给iframe父级添加-webkit-overflow-scrolling: touch无效,是因为该属性仅控制元素自身的滚动惯性效果,不会修改事件命中传递规则。
可行方案
- 方案1:给iframe的定位父容器同步添加
pointer-events: none
不要只给iframe标签本身设置pointer-events: none,需要把负责绝对定位、盖在可滚动div上层的iframe父容器也加上该属性,从容器层就跳过事件命中检测,参考代码:
如果后续需要和iframe内部内容交互,只需要在交互触发时临时移除父容器和iframe的/* iframe外层的绝对定位容器 */ .iframe-wrap { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; /* 核心:父容器必须设置该属性 */ } .iframe-wrap iframe { width: 100%; height: 100%; border: none; pointer-events: none; scrolling: no; }pointer-events: none属性,交互结束后恢复即可。 - 方案2:JS监听触摸事件手动驱动滚动
如果方案1在部分低版本iOS系统上不生效,可以直接绕开系统的手势命中逻辑,手动控制滚动:- 绑定
touchstart事件,记录初始触摸点的Y轴坐标,同时存下可滚动div当前的scrollTop值 - 绑定
touchmove事件,计算触摸点的纵向偏移量,直接设置可滚动div的scrollTop为「初始scrollTop - 纵向偏移量」 - 绑定
touchend、touchcancel事件,清空之前存储的临时坐标和scrollTop值
事件绑定时记得加{passive: true}参数,避免阻塞主线程影响滚动流畅度。
- 绑定
- 方案3:滚动过程中临时隐藏iframe
如果不需要滚动时实时展示iframe内容,可以在检测到触摸滚动触发时,给iframe设置visibility: hidden,等滚动结束200-300ms后再改回visibility: visible。这个方案性能最好,滚动时不会触发iframe的重绘重排,且切换速度极快,用户几乎感知不到闪烁。
内容的提问来源于stack exchange,提问作者Xelun
相关产品推荐
相关产品推荐

