iPhone Safari页面滚动时固定元素触摸事件无响应的技术问询
iPhone Safari滚动时固定元素触摸事件延迟触发的解决方案
问题描述
在iPhone的Safari浏览器中,当页面快速滚动时,底部固定定位的白色盒子(.fix)的触摸事件需要等待滚动完全停止后才会触发。具体表现:
- 滑动页面使其处于滚动状态,同时触摸白色盒子,事件无响应
- 页面静止时触摸该盒子,事件能正常触发
复现代码
以下是能复现该问题的完整代码:
HTML
<section class="scroll"></section> <div class="fix"> <p class="handle"></p> </div>
CSS
.scroll{ width: 100%; height: 2000vh; background: rgb(226,252,193); background: linear-gradient(0deg, rgba(226,252,193,1) 0%, rgba(182,251,176,1) 3%, rgba(204,128,151,1) 49%, rgba(134,133,189,1) 75%, rgba(71,153,222,1) 98%, rgba(0,204,247,1) 100%); } *{padding: 0;margin: 0;} .fix{ position: fixed; display: flex; align-items: center; justify-content: center; bottom: 0; left: 0; right: 0; height: 150px; background-color: #fff; } .handle{ font-size: 20px; -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Safari */ -khtml-user-select: none; /* Konqueror HTML */ -moz-user-select: none; /* Old versions of Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; }
JavaScript
const fix = document.querySelector('.fix') const text = document.querySelector('.handle') fix.addEventListener('touchstart', handle) fix.addEventListener('touchend', handle) fix.addEventListener('mousedown', handle) fix.addEventListener('touchmove', handle) function handle(e){ text.innerText = e.type console.log(e) }
问题原因
这是iOS Safari的滚动优先级优化导致的:为了保证页面滚动的流畅度,浏览器会将滚动操作交给专门的线程处理,同时在滚动期间暂时阻塞主线程上的触摸事件触发——尤其是固定定位元素,因为浏览器默认认为滚动时用户的操作目标是页面内容而非固定元素,所以会延迟触发固定元素的触摸事件,直到滚动结束。
解决方案
我们可以通过CSS的touch-action属性,明确告知浏览器底部固定元素不需要参与滚动相关的触摸行为,让浏览器优先处理该元素的触摸事件:
修改后的.fix CSS代码
.fix{ position: fixed; display: flex; align-items: center; justify-content: center; bottom: 0; left: 0; right: 0; height: 150px; background-color: #fff; /* 添加这行代码,解决触摸事件延迟问题 */ touch-action: manipulation; }
选项说明
touch-action: manipulation:允许浏览器仅处理点击和双击操作,禁用滚动、缩放等触摸行为,这样浏览器就不会在滚动时延迟该元素的触摸事件- 如果需要完全禁用浏览器默认的触摸行为(比如点击高亮),可以使用
touch-action: none,但需注意这会让所有默认触摸行为失效,需根据业务场景选择
效果验证
修改后,在iPhone Safari中滚动页面时触摸底部固定盒子,touchstart/touchend等事件会立即触发,无需等待滚动停止,和页面静止时的响应一致。
内容的提问来源于stack exchange,提问作者Nekiy2
相关产品推荐
相关产品推荐

