今天做移动端菜单适配,小屏幕时利用媒体查询,将菜单缩成一个icon,点击icon弹出侧边栏菜单
先添加一个遮罩层,然后添加菜单,菜单的zindex高于遮罩层,菜单icon的zindex高于菜单,定位固定在右上角,这样点击icon菜单滑进滑出,icon的位置不需要额外调整。
//菜单icon .navbar-icon { width: 30px; display: none; position: absolute; top: 20px; right: 20px; z-index: 101; cursor: pointer; } //菜单列表弹层 .navbar-phone{ position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 100; font-size: 14px; background-color: #fff; overflow: hidden; -webkit-transform: translateX(40%); transform: translateX(40%); } //半透明遮罩 .shadePage{ width: 100%; background: #ddd; position: fixed; top: 0; right: 0; left: 0; bottom: 0; opacity: 0.7; z-index: 99; }
基本功能做好了,但是发现弹出菜单页后,整个遮罩和菜单内容是可以随下面的页面滚动的,这显然是不符合我们需求的,原本的思路是让这个遮罩层的高度只等于屏幕高度,于是在这个坑上最走越远,查了不少资料,有的是用js动态算出屏幕高度赋值给遮罩的,有说给html,body所有父容器增加height:100%,然后容器height:100%的,但是即使遮罩高度固定,屏幕仍然可以滚动。这时候发现让遮罩充满整个屏幕的思路是错的,于是搜到了遮罩层去除滚动的。
因为项目引用了elementUI,有人说可以直接调用element提供的loading组件,调用了下,loading组件确实可以整个屏幕全屏,无滚动,但是有两个痛点,一个是有一个一直存在的loading动画,一个是遮罩的zindex是根据当前容器里元素最高的zindex动态生成的,本来遮罩的zindex是2000,我想让弹出层盖在遮罩上,设置了zindex:2004,结果页面上遮罩的zindex变成了2005。看来eleme的loading主要是用于页面过渡的,不大适合做通用的遮罩。
还有通过js阻止浏览器默认事件的,但是这样一棒子打死,弹出层若想添加滚动的内容就实现不了了。
这时候找到一篇最完美的解决方案,点击弹出的时候,给body添加overflow:hidden的样式,关闭遮罩的时候重新打开,同时打开的时候记录下当前页面滚动的位置,关闭的时候需要回归当前位置。
全局添加样式:
body.dialog-open { position: fixed; width: 100%; }
添加全局方法:
const ModalHelper = ( (bodyCls) =>{ let scrollTop; return { afterOpen: function () { scrollTop = document.scrollingElement.scrollTop; document.body.classList.add(bodyCls); document.body.style.top = -scrollTop + ‘px‘; }, beforeClose: function () { document.body.classList.remove(bodyCls); // scrollTop lost after set position:fixed, restore it back. document.scrollingElement.scrollTop = scrollTop; } }; })(‘dialog-open‘);
然后监听一下控制弹出层显示的变量,调用添加和消除样式:
watch: { phoneMenu:function(val) { if (!!val){ ModalHelper.afterOpen(); } else { ModalHelper.beforeClose(); } } }
大功告成
原文地址:https://www.cnblogs.com/yoxixi/p/9402385.html