移动端滚动iframe时禁用页面主体滚动的问题求助
问题分析
移动端的触摸事件没办法穿透iframe传递到父页面的body上,所以你监听body的touchstart/touchend事件时,触摸iframe区域根本不会触发这些事件,这就导致h1内容没变化,body滚动也没被正确禁用。另外你原来的移动端事件逻辑也有问题——touchstart就启用滚动、touchend就禁用,完全不符合“触摸iframe时禁用body滚动”的需求。
解决方案
1. 修正逻辑并直接给iframe绑定触摸事件
因为你的iframe是同域的(src为空,默认和父页面同域),可以直接给它绑定触摸事件来控制body的滚动状态,同时修复DOM标签错误(你原代码里<h1>的闭合标签写成了</p>,会导致DOM结构异常):
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> html, body { margin: 0; padding: 0; height: 100%; } #simulator { display: block; margin: 20px auto; } </style> </head> <body> <section> <iframe id="simulator" style="background: #000000;" src="" width="378px" height="1500px" frameborder="0" scrolling="no"></iframe> <h1 id="toucheventtt">dsds</h1> <script> const simulatorIframe = document.getElementById("simulator"); const statusEl = document.getElementById("toucheventtt"); function disable_scroll() { document.body.style.overflow = "hidden"; // 解决移动端弹性滚动问题:阻止body的touchmove默认行为 document.body.addEventListener('touchmove', preventTouchMove, { passive: false }); statusEl.innerHTML = "hidden"; } function enable_scroll() { document.body.style.overflow = "auto"; // 移除touchmove阻止,恢复正常滚动 document.body.removeEventListener('touchmove', preventTouchMove); statusEl.innerHTML = "auto"; } function preventTouchMove(e) { e.preventDefault(); } // 保留PC端原有逻辑 simulatorIframe.onmouseenter = disable_scroll; simulatorIframe.onmouseleave = enable_scroll; // 移动端逻辑:给iframe绑定触摸事件 simulatorIframe.addEventListener('touchstart', disable_scroll, false); // 触摸结束或意外取消时恢复滚动 simulatorIframe.addEventListener('touchend', enable_scroll, false); simulatorIframe.addEventListener('touchcancel', enable_scroll, false); // 触摸body其他区域时,确保滚动状态正常 document.body.addEventListener('touchstart', function(e) { // 判断触摸点是否在iframe外部 if (!simulatorIframe.contains(e.target)) { enable_scroll(); } }, false); </script> </section> </body> </html>
2. 关键改进点说明
- DOM标签修复:修正了
<h1>的错误闭合标签,避免DOM结构异常影响事件触发。 - iframe触摸事件绑定:直接监听iframe的触摸事件,确保触摸iframe区域时能准确切换滚动状态。
- 移动端弹性滚动处理:仅用
overflow:hidden在iOS Safari等浏览器里可能无法完全禁止弹性滚动,所以添加了touchmove事件阻止默认行为,并且在恢复滚动时移除该监听。 - 触摸区域判断:在body的
touchstart事件里判断触摸目标是否在iframe外,确保非iframe区域的触摸操作能正常触发滚动。
3. 跨域iframe的额外处理(如果后续需要)
如果你的iframe是跨域的,直接绑定触摸事件会失败,这时候需要在iframe内部页面添加触摸事件监听,通过postMessage给父页面发送状态:
- 父页面添加消息监听:
window.addEventListener('message', function(e) { // 建议把*替换成具体的iframe域名,提升安全性 if (e.origin !== '你的iframe域名') return; if (e.data === 'disableScroll') disable_scroll(); else if (e.data === 'enableScroll') enable_scroll(); }, false);
- iframe内部页面添加触摸事件:
window.addEventListener('touchstart', () => { parent.postMessage('disableScroll', '父页面域名'); }, false); window.addEventListener('touchend', () => { parent.postMessage('enableScroll', '父页面域名'); }, false); window.addEventListener('touchcancel', () => { parent.postMessage('enableScroll', '父页面域名'); }, false);
内容的提问来源于stack exchange,提问作者Pak Ho Cheung
相关产品推荐
相关产品推荐

