Javascript禁止父元素滚动条滚动, pc、移动端均有效

在网页中经常会遇到这样的场景, 网页比较长有滚动条, 然后网页内的某个内容块里面的内容也比较长, 也具有滚动条。当鼠标移到内容块中使用滚动条来滚动查看内容到达底部或头部的时候,父元素的滚动条也就开始滚动了, 非常影响体验, 特别是选择东西的时候。我们需要在滚动的时候不允许父元素也跟着滚动。有一种非常简单, 但是适应能力不强的方法就是, 给鼠标一上去的时候, 给BODY加一个css 属性overflow:hidden !important; 这个方法在部分浏览器中没有效果, 而且这个方法有个副作用,会让网页回到顶部。

 

那么我们可以通过js来实现。原理就是阻止事件冒泡和事件默认动作。阻止冒泡就为了当前块的滚动事件不会传递到父元素中, 在移动端就是touchmove事件。其实现代码如下, 通过扩展jQuery:

 

jQuery扩展代码如下:

 1 $j.fn.uniqueScroll = function () {
 2             $j(this).on('mousewheel', _pc)
 3                 .on('DOMMouseScroll', _pc);
 4 
 5             function _pc(e) {
 6 
 7                 var scrollTop = $j(this)[0].scrollTop,
 8                     scrollHeight = $j(this)[0].scrollHeight,
 9                     height = $j(this)[0].clientHeight;
10 
11                 var delta = (e.originalEvent.wheelDelta) ? e.originalEvent.wheelDelta : -(e.originalEvent.detail || 0);
12 
13                 if ((delta > 0 && scrollTop <= delta) || (delta < 0 && scrollHeight - height - scrollTop <= -1 * delta)) {
14                     this.scrollTop = delta > 0 ? 0 : scrollHeight;
15                     e.stopPropagation();
16                     e.preventDefault();
17                 }
18             }
19 
20             $j(this).on('touchstart', function (e) {
21                 var targetTouches = e.targetTouches ? e.targetTouches : e.originalEvent.targetTouches;
22                 $j(this)[0].tmPoint = {x: targetTouches[0].pageX, y: targetTouches[0].pageY};
23             });
24             $j(this).on('touchmove', _mobile);
25             $j(this).on('touchend', function (e) {
26                 $j(this)[0].tmPoint = null;
27             });
28             $j(this).on('touchcancel', function (e) {
29                 $j(this)[0].tmPoint = null;
30             });
31 
32             function _mobile(e) {
33 
34                 if ($j(this)[0].tmPoint == null) {
35                     return;
36                 }
37 
38                 var targetTouches = e.targetTouches ? e.targetTouches : e.originalEvent.targetTouches;
39                 var scrollTop = $j(this)[0].scrollTop,
40                     scrollHeight = $j(this)[0].scrollHeight,
41                     height = $j(this)[0].clientHeight;
42 
43                 var point = {x: targetTouches[0].pageX, y: targetTouches[0].pageY};
44                 var de = $j(this)[0].tmPoint.y - point.y;
45                 if (de < 0 && scrollTop <= 0) {
46                     e.stopPropagation();
47                     e.preventDefault();
48                 }
49 
50                 if (de > 0 && scrollTop + height >= scrollHeight) {
51                     e.stopPropagation();
52                     e.preventDefault();
53                 }
54             }
55         };

 

 

调用方法:

$(element).uniqueScroll();

 

 

测试代码如下:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>uniqueScroll</title>
  6     <script type="text/javascript" src="jquery-1.11.js"></script>
  7 </head>
  8 <div id="test" style="width:200px;height:300px;overflow: scroll;background: gray;">
  9     <br>1
 10     <br>1<br>1
 11     <br>1<br>1
 12     <br>1<br>1
 13     <br>1<br>1
 14     <br>1<br>1
 15     <br>1<br>1
 16     <br>1<br>1
 17     <br>1<br>1
 18     <br>1<br>1
 19     <br>1<br>1
 20     <br>1<br>1
 21     <br>1<br>1
 22     <br>1<br>1
 23     <br>1<br>1
 24     <br>1<br>1
 25     <br>1<br>1
 26     <br>1<br>1
 27     <br>1<br>1
 28     <br>1<br>1
 29     <br>1<br>1
 30     <br>1<br>1
 31     <br>1<br>1
 32     <br>1<br>1
 33     <br>1<br>1
 34     <br>1<br>1
 35     <br>1<br>1
 36     <br>1<br>1
 37     <br>1<br>1
 38     <br>1<br>1
 39     <br>1<br>1
 40     <br>1<br>1
 41     <br>1<br>1
 42     <br>1<br>1
 43     <br>1<br>1
 44     <br>1
 45 </div>
 46 <body>
 47 <br>1
 48 <br>1
 49 <br>1
 50 <br>1
 51 <br>1
 52 <br>1
 53 <br>1
 54 <br>1
 55 <br>1
 56 <br>1
 57 <br>1
 58 <br>1
 59 <br>1
 60 <br>1
 61 <br>1
 62 <br>1
 63 <br>1
 64 <br>1
 65 <br>1
 66 <br>1
 67 <br>1
 68 <br>1
 69 <br>1
 70 <br>1
 71 <br>1
 72 <br>1
 73 <br>1
 74 <br>1
 75 <br>1
 76 <br>1
 77 <br>1
 78 <br>1
 79 <br>1
 80 <br>1
 81 <br>1
 82 <br>1
 83 <br>1
 84 <br>1
 85 <br>1
 86 <br>1
 87 <br>1
 88 <br>1
 89 <br>1
 90 <br>1
 91 <br>1
 92 <br>1
 93 <br>1
 94 <br>1
 95 <br>1
 96 <br>1
 97 <br>1
 98 <br>1
 99 <br>1
100 <br>1
101 <br>1
102 <br>1
103 <br>1
104 <br>1
105 <br>1
106 <br>1
107 <br>1
108 <br>1
109 <br>1
110 <br>1
111 <br>1
112 <br>1
113 <br>1
114 <br>1
115 <br>1
116 <br>1
117 <br>1
118 <br>1
119 <br>1
120 <br>1
121 <br>1
122 <br>1
123 <br>1
124 <br>1
125 <br>1
126 <br>1
127 <br>1
128 <br>1
129 <br>1
130 <br>1
131 <br>1
132 <br>1
133 <br>1
134 <br>1
135 <br>1
136 <br>1
137 <br>1
138 <br>1
139 <br>1
140 <br>1
141 <br>1
142 <br>1
143 <br>1
144 <br>1
145 <br>1
146 <br>1
147 <br>1
148 <script>
149 
150     (function ($j) {
151         $j.fn.uniqueScroll = function () {
152             $j(this).on('mousewheel', _pc)
153                     .on('DOMMouseScroll', _pc);
154 
155             function _pc(e) {
156 
157                 var scrollTop = $j(this)[0].scrollTop,
158                         scrollHeight = $j(this)[0].scrollHeight,
159                         height = $j(this)[0].clientHeight;
160 
161                 var delta = (e.originalEvent.wheelDelta) ? e.originalEvent.wheelDelta : -(e.originalEvent.detail || 0);
162 
163                 if ((delta > 0 && scrollTop <= delta) || (delta < 0 && scrollHeight - height - scrollTop <= -1 * delta)) {
164                     this.scrollTop = delta > 0 ? 0 : scrollHeight;
165                     e.stopPropagation();
166                     e.preventDefault();
167                 }
168             }
169 
170             $j(this).on('touchstart', function (e) {
171                 var targetTouches = e.targetTouches ? e.targetTouches : e.originalEvent.targetTouches;
172                 $j(this)[0].tmPoint = {x: targetTouches[0].pageX, y: targetTouches[0].pageY};
173             });
174             $j(this).on('touchmove', _mobile);
175             $j(this).on('touchend', function (e) {
176                 $j(this)[0].tmPoint = null;
177             });
178             $j(this).on('touchcancel', function (e) {
179                 $j(this)[0].tmPoint = null;
180             });
181 
182             function _mobile(e) {
183                 if ($j(this)[0].tmPoint == null) {
184                     return;
185                 }
186 
187                 var targetTouches = e.targetTouches ? e.targetTouches : e.originalEvent.targetTouches;
188                 var scrollTop = $j(this)[0].scrollTop,
189                         scrollHeight = $j(this)[0].scrollHeight,
190                         height = $j(this)[0].clientHeight;
191 
192                 var point = {x: targetTouches[0].pageX, y: targetTouches[0].pageY};
193                 var de = $j(this)[0].tmPoint.y - point.y;
194 
195                 if (de < 0 && scrollTop <= 0) {
196                     e.stopPropagation();
197                     e.preventDefault();
198                 }
199 
200                 if (de > 0 && scrollTop + height >= scrollHeight) {
201                     e.stopPropagation();
202                     e.preventDefault();
203                 }
204             }
205         }
206     })(jQuery);
207 
208 
209     $('#test').uniqueScroll();
210 </script>
211 
212 </body>
213 </html>

 

posted @ 2016-02-26 15:58  Jinko  阅读(2164)  评论(0编辑  收藏  举报