您现在的位置:首页技术文章正文

移动端弹出不可穿透遮罩层

        相信很多写移动端的朋友会遇到这个问题,我也遇到了,之后就辛辛苦苦的在网上找解决办法,下面我大概提一下我在网上看到的几种办法,行不行的通呢?本人就亲测了下。本人学的还不是太深,如果有什么不对的地方或者有好的解决办法,也请告知。

        1.弹出层出现时给body添加一个css样式:height:100%;overflow:hidden;弹出层消失再去掉这个类。

        测试结果:chrome手机模拟器还真可以,but到了我的安卓手机上,扑街了···  


        之后又看到有人提到,是要html也设置同样的样式才会有效果,所以同样给html添加了这个类,弹出层消失时去掉这个类。

        测试结果:效果是有了,弹出层内可以滚动,底层不滚动了,but当弹出层出现,底层body会回到页面顶部,这个并不是我想要的。所以此方法XX。  


        2.弹出层出现时给body添加样式position:fixed,并算出当时页面的scrollTop滚动值,给body一个负的top值来保证body不会回到顶部,弹出层消失时恢复。


以下代码基于jquery.

var top = 0;/*给top变量一个初始值,以便下方赋值并引用*/
$('.tan').click(function(){/*点击事件弹出层显示*/
$('.div2').show(); /*弹出层出现 */
top = $(window).scrollTop();/*获取页面的scrollTop*/
$('body').css("top",-top+"px");/*给body一个负的top值*/
$('body').addClass('add');/*给body增加一个类,position:fixed*/
});
$('.close').click(function(){/*弹出层消失点击事件*/
$('.div2').hide(); /*弹出层消失*/
$('body').removeClass('add');/*去掉给body的类*/
$(window).scrollTop(top);/*设置页面滚动的高度,如果不设置,关闭弹出层时页面会回到顶部*/
});

        测试效果:安卓手机效果实现了,哈哈哈····,再测个苹果手机,嗯···?为什么苹果手机的效果这么挫,弹窗层内部滑动不是很顺畅,手滑多少页面滑多少,有点死板,不知为何?

        3.无意中发现定位层之间好像是不会传递事件的,将弹窗之外的元素包在一个div里,给这个div设置定位样式,给宽高是充满屏幕的,设置overflow:auto;这样这个div和弹出层就是两个定位层,滑动弹出层时不会传递到div上的。

/*第一种:*/
div{
position:absolute;
top:0;
bottom:0;
left:0;
overflow:auto;
}

/*第二种:*/

div{
height:100%;/*前提设置他的父元素都是100%的高才可以充满屏幕高度*/
position:absolute;
top:0;
left:0;
overflow:auto;
}

        给div设置以上两种其中一种样式就可以,第一种的bottom:0和第二种height:100%都是为了固定div的高度是屏幕的高度,overflow:auto使滚动发生在div内部,这样弹出层的滚动就不会传递给div了,如果不给设置高度,弹出层的滚动事件仍然会传递给body,div就会随着body滚动。

        测试结果:和第二个方法结果差不多,效果是有了,但是在ipone手机上定位层上下滑动效果不佳。

        这个方法是我无意中发现,本以为有简便方法可以解决,但是在苹果手机上就是不给力···

        4.最后的方法还是用到插件了,iScroll.js,这个js有自己的滑动方式,实现原理是阻止元素默认滑动事件,用这个插件自己的滑动方式实现滑动。
以下是我测试页面的全部代码:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />
<title>test</title>
<style>
#wrapper{
width:100%;
/*height:100%;*/
margin:0 auto;
overflow:hidden;
}
#wrapper input{
width: 100px;
height: 50px;
background: #CC3333;
}
#wrapper ul li{
width:100%;
height:40px;
line-height:40px;
text-align:center;
background:#09C;
font-size:22px;
color:#ffffff;
margin:10px 0px;
}
#wrapper ul li.hong{
background:#C33;
}
.main{
width:100%;
height:100%;
/*background:rgba(0,0,0,0.78);*/
position:fixed;
left:0px;
top:0px;
display:none;
}
#tan{
width:60%;
height:400px;
margin:0 auto;
overflow:hidden;
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
}
#tan ul li{
width:100%;
height:40px;
line-height:40px;
text-align:center;
background:#09C;
font-size:22px;
color:#ffffff;
margin:10px 0px;
}
.bg{
width:100%;
height:100%;
background-color: rgba(0,0,0,0.5);
position:absolute;
top:0;
left:0;
}
</style>
</head>
<body>
<div id="wrapper">
<div>
遇见,是琥珀流年中如云朵般美丽的诗篇,没有格律,没有韵脚,读之,却朗朗上口,百读不厌。人生中最难忘的,就是一次次镌刻在心灵深处的相遇。静默独处时,伤心落泪时,细细品味,点点滴滴的美好,足可以润泽晦暗枯燥的心灵。
佛曰:前生五百次的回眸才换得今生的一次擦肩而过。那么,我们的相遇、相知是前生多少次回眸才修得的缘分呢?前生太虚渺,不可知;来生有太渺远,不可测;能把握的,唯有今生。所以,珍惜今生所有的遇见。
一花一天堂,一草一世界,一树一菩提,一土一如来,一方一净土,一笑一尘缘。想来,所有的遇见,都是前世今生该有的缘分。
“同是天涯沦落人,相逢何必曾相识”是萍水相逢却又惺惺相惜的缘分, “桃花潭水深千尺,不及汪伦送我情”是高山流水、情同手足的缘分,“曾经沧海难为水,除却巫山不是云”是相识相知、执手红尘的缘分。
席慕蓉曾说:如何让你遇见我,在我最美丽的时刻,为这,我已在佛前求了五百年,求他让我们结一段尘缘。所以,不管如何,我珍惜所有的遇见。无论我们是素昧平生,还是相识相知。

<input type="button" value="点我试一下"/>

我珍惜素昧平生的朋友。虽然我们未曾谋面,可是,一声轻轻的问候,一个甜甜的笑脸,几行温馨的留言,瞬间便拂去萦绕心头的缕缕疲惫和丝丝尘埃。不为别的,只为那一份远隔千里的信任,只为那不为繁琐忙碌阻隔的真诚。虽不相见,我亦懂得,你同我一样,于茫茫人海中穿梭忙碌,于深杳红尘中为了家人奔波付出。我很珍惜,这一份静默在生命一隅的如水清澈的缘。
我珍惜生活中风雨同舟的朋友。千金易得,知己难求。朋友的真情,是人生千金难买的珍宝。也许,他(她)不会锦上添花,但是他(她)会雪中送炭。他(她)不会甜言蜜语,但是他(她)会推心置腹。伤心时,一句温馨的问候;孤独时,一次真心的陪伴;困难时,一份无私地援助:这些,都是穿透红尘冷漠的暖。所以,我很珍惜,这一份闪烁在我生命中的如阳光温暖的缘。
我珍惜和我牵手红尘的爱人。不管他前生是不是在三生石畔刻下爱情的誓言,也不管他是不是前生将我掩埋的那个人,我只知道,他是我的亲人。我们除了要平平淡淡的共度光阴,还要共同撑起家庭的未来,无论多少的风风雨雨,我们要一起面对,一起承担。我珍惜,这一份镶嵌在我生命中的如玉温润的缘。
如果,今生还有一种特殊的遇见:彼此相爱过,却无缘牵手。那么,就把这份爱安放在心灵一隅,于夜深人静时,于静默独处时,在内心深处幽幽绽放吧。纵使不能在一起,相爱过,也是人生旅途最美的一段珍藏。如果,不能继续做朋友,默默地祝福对方也好。如果不能祝福对方,各安天涯一方也好。总之,不要反目为仇,不要辜负了曾经的美好,和今生相遇的缘分。
不懂得珍惜的人,辜负了红尘中遇见的情谊,就会成为情感上的孤家寡人,就会离快乐越来越远。
遇见,是一缕清风,舒爽怡人;遇见,是一束阳光,温暖明媚;遇见,是一阕诗词,隽永灵动;遇见,是一曲清音,余音绕梁。今生相遇的人,来生不一定相见。请珍惜,今生所有的遇见!
</div>
</div>
<div class="main">
<div id="tan">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>1</li>
<li>2</li>
<li>1</li>
<li>2</li>
<li>1</li>
<li>2</li>
<li>1</li>
<li>2</li>
<li>1</li>
<li>2</li>
<li>1</li>
<li>2</li>
</ul>
</div>
</div>
<script src="js/jquery-2.1.1.min.js"></script>
<script src="js/iscroll.js"></script>
<script type="text/javascript">
$(function(){
$("#wrapper").find("input").click(function(){
$(".main").show();/*弹出层显示*/
$('.bg').on('touchmove', function (e) { e.preventDefault(); }, false);/*弹出层的背景层阻止默认滑动事件*/
new IScroll('#tan');
});
$(".main").click(function(){
$(".main").hide();
});
});
</script>
</body>
</html>


        原理是:弹出层分两层,一个是滑动层tan,一个是背景层bg,给背景层阻止默认滑动事件,这样滑动它的时候不会影响底层,滑动层tan用了插件的滑动方式,也不会传递底层,这样就解决的滑动层滑动而body不滚动。


        此方法是没有阻止body的滚动,而是阻止了传递滑动事件的发生。

        测试结果:完美!


        找到了这个方法之后我一直对第二种和第三种出现的问题不死心,代码不是太多,又不用引用插件,多方便啊,在ipone手机上为什么会滑动卡顿呢?所以我继续研究,终·······于········知道了解决办法,(^o^)/

        有一个这样的样式属性不知道大家是否知晓:

    -webkit-overflow-scrolling : touch; //可以让页面在Native端滚动时模拟原生的弹性滚动效果

        在需要滚动的元素上加上这个,第二、三种出现的问题就解决了,够我高兴好久了。

        因为对于这个了解的不多,就查了一下是否会带来什么不良影响,以下是网上看到的有人遇到的问题并如何解决的:
        http://www.tuicool.com/articles/U73Erq/
        http://www.111cn.net/cssdiv/css/108397.htm  

        总结下来,使用这个需要注意的问题有以下几个方面
        1.会影响层级,需处理好层级关系
        2.不要将此属性加在body上,否则会有部分浏览器白屏,需加在滚动元素上
        3.设置scrollTop值时需注意此属性的影响
        4.创建了带有硬件加速的系统级控件,所以效率很高。但是相对耗更多内存,最好在产生了非常大面积的overflow时才应用。

        因为也是从网上找的,所以并不完全保证其准确性,大家如果有用到的根据自己的实际情况采取相应的措施吧。

        OK,回到这篇博文的主题,亲测了几种方法之后后三种都是可以实现效果的,所以结果还是不错的,至于使用哪种更好,谁需要用自己去考虑吧······ (^o^)/


发表评论

头像:
名称:
内容:
表情板
提交留言