zoukankan      html  css  js  c++  java
  • h5页面弹窗滚动穿透的思考

      可能我们经常做这样的弹窗对吧,兴许我们绝对很简单,两下搞定:

      弹窗的页面结构代码:

    		<!-- 弹窗模块  引用时移除static_tip类-->
    		<div class="mask" ontouchstart = "return false" style="display:none"></div>
    		<div class="main_venue_tip" style="display:none">
    			<i class="close"></i>
    			<div class="h_tit">
    				<i>新用户首单送券活动规则</i>
    			</div>
    			<div class="main_v_tcon scroll" id="scroll" style="overflow-y:auto;-webkit-overflow-scrolling:touch;">
    					<p>(一)活动时间</p>
    					<p>2015年8月12日9:00:00-8月20日23:59:59</p>
    					<p>(二)活动限制:</p>
    					<p>1)参与活动用户须已有绑定微信账号的京东账号;</p>
    					<p>2)每个京东用户最多可获得2张不同面额的优惠券。不同微信号绑定同一京东账号多次参与活动的,则第一个参与本次活动的账号参与结果有效,其余账号参与结果均视为无效。</p>
    					<p>(三)参与方式:
    	用户进入活动页点击“用钱砸”,完成转发好友和分享朋友圈的操作,即可有机会获得面额不等的优惠券。</p>
    					<p>(四)活动奖券:</p>
    					<p>1)奖品内容:本次活动以7元到77元不等面额优惠券组成,奖品数量有限,先到先</p>
    					<p>1)奖品内容:本次活动以7元到77元不等面额优惠券组成,奖品数量有限,先到先</p>
    					<p>1)奖品内容:本次活动以7元到77元不等面额优惠券组成,奖品数量有限,先到先</p>
    					<p>1)奖品内容:本次活动以7元到77元不等面额优惠券组成,奖品数量有限,先到先</p>
    					<p>1)奖品内容:本次活动以7元到77元不等面额优惠券组成,奖品数量有限,先到先</p>
    					<p>1)奖品内容:本次活动以7元到77元不等面额优惠券组成,奖品数量有限,先到先</p>
    					<p>1)奖品内容:本次活动以7元到77元不等面额优惠券组成,奖品数量有限,先到先</p>
    			</div>
    		</div>

       但是产品妹子要求,不能穿透底部滑动,那就bug了

      其实做为码奴的我,感觉效果不是蛮好的吗,只是内部滑动,滑到顶部,或滑到底部的时候,会出现穿透底部的滚动条。

      为了让产品那边通过,鉴于这个问题,我思考了两种办法。

      第一种,简单粗暴,这个内容滑动过程都交由js事件来完成(类似用iscroll.js实现滚动),那我们的最后效果将是下图

      内容里面变的没有滚动条,弹窗模块touchmove的时候e.preventDefault(),通过脚本滑动,代码如下(其实就是自己写个与iscroll类似的单一功能插件,苦逼吧,做码奴就是这样折腾人),还是上干货,就是这样:

    	~function(window,undefined){		
            prefix= function(){
                var _elementStyle = document.createElement('div').style;
                var vendors = ['msT','MozT', 'webkitT', 't'],
                        transform,
                        i = 0,
                        l = vendors.length;
                for ( ; i < l; i++ ) {
                    transform = vendors[i] + 'ransform';
                    if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1);
                }
                return false;
            } ();
    
    		function Scroll(opts){
    			this.scrollElem = opts.scrollElem,
    			this.scrollCon = opts.scrollCon,
    			this.scrollwp = opts.scrollwp,
    			this.CH = opts.scrollCon.offsetHeight - opts.scrollwp.offsetHeight,
    			this.moveDis = 0,
    			this.touchbool = false;
    			this.init();
    		}
    		Scroll.prototype = {
    			constructor:"Scroll",
    			tweenmove:function(dis){
    				var self = this;
    				self.scrollCon.style.cssText = "-"+prefix+"-transform:translateY("+dis+"px) translateZ(0);-"+prefix+"-transition:-"+prefix+"-transform 0.2s linear";
    			},
    			move:function(dis){
    				var self = this;
    				self.scrollCon.style.cssText = "-"+prefix+"-transform:translateY("+dis+"px) translateZ(0)";
    			},				
    			init:function(){
    				var _this = this,moveY,touchY;
    				_this.scrollElem.addEventListener("touchstart",function(e){
    					var e = e || window.event,
    				        touch=e.touches[0];
    				        e.preventDefault();
    						touchY = touch.pageY;
    						 _this.touchbool = true;
    					if(e.target.className.replace(/^s$/g,"") == "close"){
    						tip.style.display = "none";
    						mask.style.display = "none";
    					}
    				},false);
    				_this.scrollElem.addEventListener("touchmove",function(e){
    					var e = e || window.event;
    					e.preventDefault();
    					if(_this.touchbool){
    						var touch=e.touches[0];
    							moveY = touch.pageY;						
    						if(moveY-touchY+_this.moveDis < 20 && moveY-touchY+_this.moveDis >(-_this.CH-20) ){
    							_this.move(moveY-touchY+_this.moveDis);
    						}
    					}
    				},false);
    				_this.scrollElem.addEventListener("touchend",function(e){
    					_this.moveDis = moveY-touchY+_this.moveDis;
    					if(_this.moveDis>=0){
    						_this.tweenmove(0);
    						_this.moveDis = 0;
    					}else if(_this.moveDis <= -_this.CH){
    						_this.tweenmove(-_this.CH);
    						_this.moveDis = -_this.CH;
    					}
    					 _this.touchbool = false;
    				},false);				
    			}
    		}
    		window.Scroll = Scroll;
    		var tipa = document.getElementById("tipa"),
    			close = document.querySelector(".close"),
    			tip = document.querySelector(".main_venue_tip"),
    			scrollwp = document.querySelector(".main_v_tcon"),
    			scrollCon = document.querySelector(".scroll_con"),
    			mask = document.querySelector(".mask");
    
    		var scroll = new Scroll({
    			scrollElem : tip,
    			scrollwp : scrollwp,
    			scrollCon : scrollCon
    		})
    
    		tipa.addEventListener("click",function(){
    			tip.style.display = "block";
    			mask.style.display = "block";
    			scroll.CH = scrollCon.offsetHeight - scrollwp.offsetHeight;
    		},false);	
    
    	}(window)
    

      第二种,优雅一点,当弹窗显示的时候,让根元素html的高度变成height:100%,overflow:hidden,这样确实解决了弹窗滑动底部不穿透的问题(不要给body height:100%)

      不多说,上干货

        ~function(window,undefined){    
            var tipa = document.getElementById("tipa"),
                close = document.querySelector(".close"),
                tip = document.querySelector(".main_venue_tip"),
                scrollwp = document.querySelector(".main_v_tcon"),
                scrollCon = document.querySelector(".scroll_con"),
                mask = document.querySelector(".mask"),scrollTop;
                tipa.addEventListener("click",function(){
                    tip.style.display = "block";
                    mask.style.display = "block";
                    //弹出的时候记录值
                    scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
                    document.documentElement.style.cssText="height:100%;overflow:hidden;position: relative;";
                    document.querySelector(".main_bg").style.cssText = "100%;overflow:hidden"
                },false);    
                close.addEventListener("click",function(){
                    document.body.removeAttribute("style");
                    document.querySelector(".main_bg").removeAttribute("style");    
                    //隐藏弹窗是,让滚动条滚动到记录的值
                    document.documentElement.scrollTop = document.body.scrollTop = scrollTop;
                    tip.style.display = "none";
                    mask.style.display = "none";                    
                },false)
        }(window)

      最后要注意的是,第二种方案在手q的项目表现很差,uc,微信效果ok(andriod2.3不支持内部滚动啊注意)。

      记录遇到的点滴问题,欢迎拍砖,讨论!

      

    参考资料:

      移动页面滚动穿透如何解决

  • 相关阅读:
    线程池小结(一)
    [转]ViewPager学习笔记(一)——懒加载
    [转]Private Libraries、Referenced Libraries、Dependency Libraries的区别
    关于context你必须知道的一切
    【转】在mac上配置安卓SDK
    【转】HTTP中的长连接和短连接分析
    中间件解析FDMEMTABLE.delta生成SQL的方法
    delphi 中配置文件的使用(*.ini)和TIniFile 用法
    Delphi 字符串加密与解密函数
    Delphi编写的等长加密与解密
  • 原文地址:https://www.cnblogs.com/pingfan1990/p/4899931.html
Copyright © 2011-2022 走看看