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

背景:

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

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

一气之下自己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/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏有趣的django

博客园美化大全

37500
来自专栏九彩拼盘的叨叨叨

我们到底需不需要 jQuery

曾经,在那个 IE6 还是主流浏览器的时代,为了实现稍微复杂一点的功能,也需要很多代码。如果要做到兼容主流浏览器,更需大费周章。当 jQuery 出现后,使用 ...

8110
来自专栏一“技”之长

iOS动画开发之三——UIView的转场切换 原

        前两篇博客中,我们分别介绍了UIView动画的两种使用方式,分别为,带block的方式:http://my.oschina.net/u/2340...

9210
来自专栏程序员的诗和远方

Tips-移动端滑动固顶效果(position: sticky)

先放个图看看滑动固顶是啥效果: image.png 中间那个 tab 条,平常的时候是固定的,等到页面滑上去的时候,又像 fixed 一样贴在顶部。 pos...

38560
来自专栏Spring相关

Vue中父组件向子组件传值

35910
来自专栏埋名

React UI 组件库【uiw】发布

高品质的UI工具包,基于React 16+的组件库。 ? 为了表示支持,点击 阅读原文 搞点Star,多多益善。

21020
来自专栏用户3030674的专栏

Android5.0新特性之——控件移动动画(初级)

最近开发,UI大牛们设计了好多很炫酷吊炸天的动画,不由得重新学习了一下5.0的ObjectAnimator动画。

15220
来自专栏hbbliyong

基于Three.js的360度全景--photo-sphere-viewer--简介

这个是基于three.js的全景插件  photo-sphere-viewer.js  ————————————————————————————————————...

88290
来自专栏Material Design组件

Human Interface Guidelines —— Scroll Views

40280
来自专栏偏前端工程师的驿站

CSS魔法堂:Transition就这么好玩

 以前说起前端动画必须使用JS,而CSS3为我们带来transition和@keyframes,让我们可以以更简单(声明式代替命令式)和更高效的方式实现UI状态...

13130

扫码关注云+社区

领取腾讯云代金券