背景:
弹层里边有可滚动区域时,在移动端的坑我就不多说了。
找了很多解决滚动穿透的方案,最终都不能完美解决。
一气之下自己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/