背景:

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

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

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

转载于:https://www.cnblogs.com/padding1015/p/10028111.html

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

  1. 滚动html颜色,DIV 自动滚动功能及滚动条颜色修改的代码

    废话不多说了,直接给大家贴代码了.具体代码如下所示: 1.DIV 自动滚动 function startmarquee(lh, speed, delay) { var t; var oHeight = ...

  2. 解决弹出框滚动穿透的问题(问题是body也会滚动)

    解决弹出框滚动穿透的问题(问题是body也会滚动) 参考文章: (1)解决弹出框滚动穿透的问题(问题是body也会滚动) (2)https://www.cnblogs.com/ghfjj/p/8317 ...

  3. uniapp 自定义弹层时,底部页面滚动而弹层不能滚动

    今天做页面有个需求: 页面有个列表(A),内容过多时需要滚动, 然后做了个弹层,里面也有个列表(B),内容过多时需要滚动 由于A列表使用的web-view组件,而B列表使用view组件加overflo ...

  4. JS PC端时间日历插件 功能齐全 无依赖

    时间日历插件,网上有很多版本,功能强大的,功能简单的数不尽数,那为什么我还要写一个日历插件呢? 很认真的告诉你: 我手痒了,就是闲下来随便敲敲. 开发一个功能齐全的日期选择插件 根据自己的业务需求不断 ...

  5. Clipboard.js移动端【ios】复制事件不生效解决方法

    在需要添加复制事件的元素增加Css样式: cursor: pointer; 要给点击复制的按钮加这个属性才能在移动端好用. 苹果和安卓百分百好用. // $(function(){// var cli ...

  6. DIV 自动滚动功能及滚动条颜色修改

    1.DIV 自动滚动 <script type="text/javascript"> function startmarquee(lh, speed, delay) { ...

  7. css 超出隐藏滚动条_css 之内容溢出滚动,隐藏滚动条(解决火狐浏览隐藏不了滚动条问题)...

    解决火狐浏览隐藏不了滚动条问题 1.里层容器的width多17px,外层容器溢出隐藏,能兼容各个浏览器 .outContainer { width:350px; height:300px; overf ...

  8. 弹层蒙版(mask),ios滚动穿透,我们项目的解决方案

    问题描述 项目开发遇到一个ios独有的问题,在wkwebview中稳定复现 问题: 弹出一个蒙版,当在蒙版上面滑动的时候蒙版后面的内容滚动了 这当然是ios的bug,但是经过我们测试iphone7也会 ...

  9. animate inater插件_基于animate.css动画库的全屏滚动小插件,适用于vue.js(移动端、pc)项目...

    功能简介 基于animate.css动画库的全屏滚动,适用于vue.js(移动端.pc)项目. 安装 npm install vue-animate-fullpage --save 使用 main.j ...

最新文章

  1. Linux 进程等待队列
  2. 【MyBatis】学习纪要六:动态SQL
  3. 等我敲完这行代码,就和你离婚!
  4. GPU Saturday技术沙龙:OpenCL程序员眼中的下一代APU架构
  5. 树状数组入门(有被精简的树状数组所震撼到)
  6. C++类成员属性的一种简洁实现
  7. mysql之批量删除
  8. java url json字符串_Java和PHP的JSON字符串转URL参数方法
  9. Js参数RSA加密传输,jsencrypt.js的使用
  10. 微信公众平台开发概述
  11. 听说你要找前端工作,写一个酷炫的动画的简历呀
  12. 阿里云盘 网页版地址 阿里云盘pc版 阿里云盘下载
  13. PS新手教程,教你打造一个炫酷的冰冻字效_桂桂博客
  14. STM32F7--->Internal Flash
  15. Android 获取手机状态栏高度
  16. LWIP 以太网先启动后插入网线无法入网的解决办法
  17. Homa: A Receiver-Driven Low-Latency Transport Protocol Using Network Priorities(Sigcomm'18) 论文记录
  18. python3根据RGB像素点生成图片
  19. DT_MACHINE_START 板级信息初始化匹配调用机制实现
  20. vs2017c语言一闪而逝6,Visual Studio IDE编写程序时不显示窗口或窗口一闪而逝的解决方法...

热门文章

  1. 岭回归,Lasso回归及弹性网络回归原理及R实现
  2. 正确实现AutoCAD布局打印过程详解
  3. 以太网监控2022年应当关注的关键挑战和解决方案
  4. neauscan自带软件scan导出的.avg格式文件如何在matlab里面画图
  5. 戴尔新BIOS设置U盘启动
  6. 如何在寒武纪MLU220-SOM上实现NTP自动校时
  7. vscode 自定义注释
  8. mysql jdbc批处理_JDBC批处理 数据库连接池
  9. 浅谈SPAD的落地应用
  10. 华为设备配置基于VLAN的二层协议透明传输