h5頁面彈窗滾動穿透的思考

  可能咱們常常作這樣的彈窗對吧,興許咱們絕對很簡單,兩下搞定:css

  彈窗的頁面結構代碼:html

		<!-- 彈窗模塊  引用時移除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了web

  其實作爲碼奴的我,感受效果不是蠻好的嗎,只是內部滑動,滑到頂部,或滑到底部的時候,會出現穿透底部的滾動條。segmentfault

  爲了讓產品那邊經過,鑑於這個問題,我思考了兩種辦法。微信

  第一種,簡單粗暴,這個內容滑動過程都交由js事件來完成(相似用iscroll.js實現滾動),那咱們的最後效果將是下圖this

  內容裏面變的沒有滾動條,彈窗模塊touchmove的時候e.preventDefault(),經過腳本滑動,代碼以下(其實就是本身寫個與iscroll相似的單一功能插件,苦逼吧,作碼奴就是這樣折騰人),仍是上乾貨,就是這樣:spa

	~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%)prototype

  很少說,上乾貨插件

    ~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不支持內部滾動啊注意)。3d

 

 

  記錄遇到的點滴問題,歡迎拍磚,討論!

  

參考資料:

  移動頁面滾動穿透如何解決

相關文章
相關標籤/搜索