js - 移动端的超出滚动功能,附带滚动条,可解决弹层中滚动穿透问题。

背景:

弹层里边有可滚动区域时,在移动端的坑我就不多说了。

找了很多解决滚动穿透的方案,最终都不能完美解决。

一气之下自己js撸了一个。

效果图:

js - 移动端的超出滚动功能,附带滚动条,可解决弹层中滚动穿透问题。_第1张图片

 

原理:

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/

你可能感兴趣的:(js - 移动端的超出滚动功能,附带滚动条,可解决弹层中滚动穿透问题。)