背景:
弹层里边有可滚动区域时,在移动端的坑我就不多说了。
找了很多解决滚动穿透的方案,最终都不能完美解决。
一气之下自己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">Xspan> 5 h3> 6 <div class="lose-list"> 7 <ul class="layer-scroll"> 8 <li class="lose-item"> 9 <h3>有效降价车款1h3> 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>有效降价车款2h3> 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/