移動端的超出滾動功能,附帶滾動條,可解決彈層中滾動穿透問題。
阿新 • • 發佈:2019-02-06
背景:
彈層裡邊有可滾動區域時,在移動端的坑我就不多說了。
找了很多解決滾動穿透的方案,最終都不能完美解決。
一氣之下自己js擼了一個。
效果圖:
原理:
1、解決滾動穿透:通過給彈層繫結touchmove和mousewheel事件,取消預設行為實現。
2、取消預設行為後不能滾動:給需要滾動展示的區域繫結touchstart、touchmove和mousewheel事件,監聽觸發區域的Y值,對應修改可滾動區域的translateY值,實現滾動效果。
缺點/不足:
滑動起來略顯示卡頓,使用者體驗不好,有大佬給提示下怎麼優化嗎?
程式碼:
1 <div class="layer"> 2 <div class="layer-box"> 3 <h3>title 4 <span class="close">X</span> 5 </h3> 6 <div class="lose-list"> 7 <ul class="layer-scroll"> 8 <li class="lose-item"> 9 <h3>有效降價車款1</h3> 10 <ul class="lose-date"> 11 <li>10月7日5分</li> 12 <li>10月7日6分</li> 13 <li>10月7日7分</li> 14 <li>10月7日8分</li> 15 <li>10月7日9分</li> 16 <li>10月7日10分</li> 17 <li>10月7日11分</li> 18 <li>10月7日12分</li> 19 <li>10月7日13分</li> 20 <li>10月7日14分</li> 21 <li>10月7日15444分</li> 22 </ul> 23 </li> 24 <li class="lose-item"> 25 <h3>有效降價車款2</h3> 26 <ul class="lose-date"> 27 <li>10月7日5分</li> 28 <li>10月7日6分</li> 29 <li>10月7日7分</li> 30 <li>10月7日8分</li> 31 <li>10月7日9分</li> 32 <li>10月7日10分</li> 33 <li>10月7日11分</li> 34 <li>10月7日12分</li> 35 <li>10月7日13分</li> 36 <li>10月7日14分</li> 37 <li>10月7日15333分</li> 38 </ul> 39 </li> 40 <li class="lose-item"> 41 <h3>有效降價車款3 </h3> 42 <ul class="lose-date"> 43 <li>10月7日5分</li> 44 <li>10月7日6分</li> 45 <li>10月7日7分</li> 46 <li>10月7日8分</li> 47 <li>10月7日9分</li> 48 <li>10月7日10分</li> 49 <li>10月7日11分</li> 50 <li>10月7日12分</li> 51 <li>10月7日13分</li> 52 <li>10月7日14分</li> 53 <li>10月7日152222分</li> 54 </ul> 55 </li> 56 </ul> 57 <div class="right-bar"> 58 <div class="bar-pro"></div> 59 </div> 60 </div> 61 </div> 62 </div>
1 myScroll({ 2 openBtn: 'button', 3 layer: '.layer', 4 client: '.lose-list', 5 scroll: '.layer-scroll', 6 barBG: '.right-bar', 7 bar: '.bar-pro' 8 }); 9 function myScroll(params) { 10 var utils = { 11 clientH: $(params.client).height(), //h1 12 scrollH: $(params.scroll).height(), //h2 13 barBgH: $(params.barBG).height() //h4 14 } 15 var lastY = 0, 16 transY = 0, 17 barTransY = 0, 18 barH = 0; //h3 19 function noScroll(dom) { 20 $(dom).on('mousewheel', function (e) { 21 e.preventDefault(); 22 }); 23 $(dom).on('touchmove', function (e) { 24 e.preventDefault(); 25 }); 26 } 27 function touchToBottom(target, bar) { 28 $(target).on('touchstart', function (e) { 29 e.preventDefault(); 30 let y = e.originalEvent.touches[0].pageY; 31 lastY = y; 32 }); 33 $(target).on('touchmove', function (e) { 34 e.preventDefault(); 35 let y = e.originalEvent.touches[0].pageY, 36 moveY = y - lastY; 37 transY += moveY; 38 if (moveY > 0 && transY > 0) { 39 /* 滑鼠向下移動,對應元素向上回看 */ 40 transY = 0; //到頂 41 } else { 42 /* 滑鼠向上移動,對應元素向下翻看 */ 43 if (Math.abs(transY) >= e.currentTarget.clientHeight - utils.clientH) { //觸底 44 transY = -(e.currentTarget.clientHeight - utils.clientH) + 1; 45 } 46 } 47 $(this).css('transform', `translate(0px, ${transY}px)`); 48 /* 移動時,滾輪的變化監聽 */ 49 var barMove = Math.abs(moveY) * utils.barBgH / utils.scrollH; 50 if (moveY > 0) { 51 barMove = -barMove; 52 } 53 barTransY += barMove; 54 if (moveY > 0) { 55 if (barTransY <= 0) { 56 barTransY = 0; //到頂 57 } 58 } else { 59 if (barTransY >= utils.barBgH - barH) { 60 barTransY = utils.barBgH - barH; //到底 61 } 62 } 63 $(bar).css('transform', `translate(0px, ${barTransY}px)`); 64 lastY = y; 65 }); 66 /* 滾輪事件 */ 67 $(target).on("mousewheel", function (e, delta) { 68 e.preventDefault(); 69 let y = e.originalEvent.deltaY; 70 if (y > 0) { 71 /* 向下翻滾輪 wheelDeltaY的值與之相反*/ 72 transY -= 100; 73 barTransY += 100 * utils.barBgH / utils.scrollH; 74 if (Math.abs(transY - 100) >= e.currentTarget.clientHeight - utils.clientH) { //觸底 75 transY = -(e.currentTarget.clientHeight - utils.clientH) + 1; 76 } 77 if (barTransY > utils.barBgH - barH) { 78 barTransY = utils.barBgH - barH 79 } 80 } else { 81 /* 向上翻滾輪*/ 82 transY += 100; 83 barTransY -= 100 * utils.barBgH / utils.scrollH; 84 if (Math.abs(transY) - 100 <= 0) { 85 transY = 0; //到頂 86 } 87 if (barTransY <= 0) { 88 barTransY = 0; //到頂 89 } 90 } 91 $(this).css('transform', `translate(0px, ${transY}px)`); 92 $(bar).css('transform', `translate(0px, ${barTransY}px)`); 93 }); 94 } 95 noScroll(params.layer); 96 $(params.layer + ' .close').on('click', function () { 97 $(params.layer).fadeOut(); 98 // $(params.scroll).css('transform', 'translate(0px, 0px)'); 99 // $(params.bar).css('transform', 'translate(0px, 0px)'); 100 }); 101 $(params.openBtn).on('click', function () { 102 $(params.scroll).css('transform', 'translate(0px, 0px)'); 103 $(params.bar).css('transform', 'translate(0px, 0px)'); 104 lastY = 0; 105 transY = 0; 106 barTransY = 0; 107 $(params.layer).fadeIn(); 108 utils = { 109 clientH: $(params.client).height(), //h1 110 scrollH: $(params.scroll).height(), //h2 111 barBgH: $(params.barBG).height() //h4 112 } 113 barH = parseInt(utils.clientH * utils.barBgH / utils.scrollH); //h3 114 $(params.bar).height(barH + 'px'); 115 if (utils.clientH < utils.scrollH) { 116 touchToBottom(params.scroll, params.bar); 117 } 118 }); 119 } 120
完整demo見github:
宣告:
請尊重部落格園原創精神,轉載或使用圖片請註明:
博主:xing.org1^
出處:http://www.cnblogs.com/padding1015/