JS - 弹出自定义层时,阻止触摸事件造成页面滚动(H5移动开发)
使用H5进行移动App开发时,常常会需要使用自定义的div层来实现一些弹出窗口。比如下面样例,点击“删除”按钮后,会弹出个确认框(其实就是个div)。同时为了让效果更好,后面还加了半透明的黑色背景遮罩层。


问题描述:
但如果这个页面太长,原来就有滚动条。那么消息框弹出后,我们还是可以通过手指上下拖动页面。用户体验不好。

问题解决:
我们在页面上添加一个触摸移动(touchmove)监听,当在消息框弹出的状态下,阻止触摸事件。这样就让这个消息框变成模态窗口,不管如何拖动,整个页面都是不会移动的。
完整代码:
(高亮处是触摸相关的关键代码)
<!DOCTYPE html> <html> <head> <meta content="telephone=no" name="format-detection" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/> <title>自定义弹出框</title> </head> <style> *{ font-size: 1rem; } .bg { display: none; position: absolute; top: 0%; left: 0%; width: 100%; height: 100%; background-color: black; z-index: 1001; -moz-opacity: 0.7; opacity: .70; filter: alpha(opacity=70); } .infobox_bg { display: none; position: absolute; padding: 8px; border: 8px solid #E8E9F7; background-color: white; z-index: 1002; overflow: auto; -moz-border-radius: 15px; -webkit-border-radius: 15px; border-radius: 15px; box-sizing: border-box; } .infobox_title { width: 100%; height: 44px; line-height: 44px; text-align: center; border-bottom: 1px solid #d9d9d9; color: #e58d05; font-size: 1.1rem; background: #f4f5f6; border-radius: 5px 5px 0 0; background-color: white; } .infobox_button{ width: 100%; padding: 3% 0; font-size: 1.1rem; color: #ffffff; background: #49BDCE; text-align: center; border-radius: 5px;" } .infobox_button:hover{ background: #1A8E9F; } </style> <script> //记录是否阻止滚动 var disableScroll = false; //如果弹出对话框时,底层的视图就不让滚动了 document.addEventListener('touchmove', function(e) { if(disableScroll){ e.preventDefault(); } }, false); //显示弹出框 function showInfoBox(){ //禁止滚动 disableScroll = true; //设置背景遮罩的尺寸 var ch=document.documentElement.clientHeight;//屏幕的高度 var cw=document.documentElement.clientWidth;//屏幕的宽度 var bgWidth = Math.max(document.body.scrollWidth,cw); var bgHeight = Math.max(document.body.scrollHeight,ch); document.getElementById("bgMask").style.width = bgWidth+"px"; document.getElementById("bgMask").style.height = bgHeight+"px"; //设置消息弹出框位置(屏幕居中) var st=document.documentElement.scrollTop||document.body.scrollTop;//滚动条距顶部距离 var sl=document.documentElement.scrollLeft||document.body.scrollLeft;//滚动条距左距离 var objH=document.getElementById("infoBox").style.height;//浮动对象的高度 var objW=document.getElementById("infoBox").style.width;//浮动对象的宽度 var objT=Number(st)+(Number(ch)-parseFloat(objH))/2; var objL=Number(sl)+(Number(cw)-parseFloat(objW))/2; document.getElementById("infoBox").style.left = objL+"px"; document.getElementById("infoBox").style.top = objT+"px"; //显示背景遮罩 document.getElementById("bgMask").style.display="block"; //显示消息弹出框 document.getElementById("infoBox").style.display="block"; } //隐藏弹出框 function hideInfoBox(){ //允许滚动 disableScroll = false; //隐藏背景遮罩 document.getElementById("bgMask").style.display="none"; //隐藏消息弹出框 document.getElementById("infoBox").style.display="none"; } </script> <body> <table align="center" border="1" cellpadding="3" cellspacing="2" bordercolor="#C0C0C0" style="width:90%;border-style:solid;text-align:left;border-collapse:collapse;"> <tbody> <tr style="background-color:#FDFDDF;height:70px"> <td><span style="font-weight: bold;"> 条目</span></td> <td width="100px;"><span style="font-weight: bold;"> 操作</span></td> </tr> <tr style="height:70px"> <td> 这个是条目1</td> <td> <button onclick="showInfoBox()">删除</button></td> </tr> <tr style="height:70px"> <td> 这个是条目2</td> <td> <button onclick="showInfoBox()">删除</button></td> </tr> <tr style="height:70px"> <td> 这个是条目3</td> <td> <button onclick="showInfoBox()">删除</button></td> </tr> <tr style="height:70px"> <td> 这个是条目4</td> <td> <button onclick="showInfoBox()">删除</button></td> </tr> <tr style="height:70px"> <td> 这个是条目5</td> <td> <button onclick="showInfoBox()">删除</button></td> </tr> <tr style="height:70px"> <td> 这个是条目6</td> <td> <button onclick="showInfoBox()">删除</button></td> </tr> <tr style="height:70px"> <td> 这个是条目7</td> <td> <button onclick="showInfoBox()">删除</button></td> </tr> <tr style="height:70px"> <td> 这个是条目8</td> <td> <button onclick="showInfoBox()">删除</button></td> </tr> <tr style="height:70px"> <td> 这个是条目9</td> <td> <button onclick="showInfoBox()">删除</button></td> </tr> </tbody> </table> <!--遮罩层--> <div id="bgMask" class="bg"></div><!--灰度背景--> <!--弹出框--> <div id="infoBox" style="width:300px;height:150px;" class="infobox_bg"> <div class="infobox_title">确定要删除吗?</div> <div class="infobox_button" style="margin-top:25px" onclick="hideInfoBox();"> 确定 </div> <div> </body> </html>