模擬滾動條

在工做中常常會遇到內容會超出固定的一個範圍,超出的內容通常會使用到滾動條來滾動顯示。javascript

可是用瀏覽器默認的滾動條常常被產品經理鄙視,但是用css卻改變不了滾動條的樣式,還好,有萬能的js ^_^~~css

網上有各類各樣的插件,但最順手的仍是本身寫的,還能夠一邊擼一邊當學習,本身動手豐衣足食  (*^__^*)html

 

其中這三個問題深深地困擾我:

一、滾動條高度java

二、每次點擊向上、向下按鈕的時候滾動條應該移動多少距離jquery

三、每拖動1px滾動條,頁面須要移動多少?瀏覽器

 

整個的框架大概是長這樣的:app

 

 

 

先來看看第一個問題。框架

  因爲目前已經知道內容區域的高度和內容可視高度以及滾動條可滾動區域的高度了,因爲內容區域與滾動條每次移動的距離都是成正比的,因此第一個問題很好解決:ide

  滾動條可移動範圍 / 滾動條高度 = 內容高度 / 內容可視高度學習

 

每次點擊按鈕的時候滾動條應該移動多少距離?

  這裏我是給參數distance設置一個值來決定每次點按鈕的時候,內容區域應該滾動多少的距離。改變這個值能夠改變內容區域滾動的快慢,若是有更好的處理方法和建議記得告訴我喔~

目前,內容區域每次滾動的距離是知道了,剩下的是計算滾動條相對於應該移動多少距離?

  滾動條可移動範圍 /滾動條每次移動距離 = 內容區域高度 / 內容區域每次移動多少距離

 

效果以下:

 

 

這裏還有一個問題,就是同時還得區分是單次點擊仍是長按。

因此得判斷一下從按下按鈕到鬆開時候的時長,目前設置爲<100ms爲單次點擊,不然爲長按:

 

 

拖動滾動條的時候,每移動1px滾動條,內容區域須要移動多少?

  先知道每1PX的距離佔滾動條可移動範圍的百分之幾,再用內容區域高度除以所得的這個百分比,就得出滾動條每移動1px內容區域相對滾動多少距離了。

  內容區域滾動的距離 = 內容區域高度 / (滾動條滾動區域 / 1)

 

 

demo完整代碼以下:

注意:

  由於用的是seajs寫的,因此稍微留意下文件的加載狀況啦

 

css:

1     .wapper{scrollbar-3dlight-color:#000; position:relative; height:302px;width:300px;overflow:hidden;margin:0 auto;line-height:40px;text-align:center;}
2     .area{background-color:#E2E2EF;width:100%; position:absolute;top:0px;left:0px;}
3     .bar{position:absolute;top:0px;right:0px; height:100%;width:1rem;background-color:#ccc;}
4     .scroll,.middle,.forward,.backward{display:block;cursor:pointer;position:absolute;right:0px;width:100%;}
5     .forward,.backward{height:16px;background-color:#6868B1;}
6     .middle{background-color:rgba(255, 255, 255, 0.22);top:16px;cursor:auto;}
7     .scroll{position:absolute;top:0px;background-color:#C2C2E9;}
8     .forward{top:0px;}
9     .backward{bottom:0px;}
View Code

 

html:

 1 <div class="wapper">
 2     <div class="area">
 3         <p>一、this is content</p>
 4         <p>二、this is content</p>
 5         <p>三、this is content</p>
 6         <p>四、this is content</p>
 7         <p>五、this is content</p>
 8         <p>六、this is content</p>
 9         <p>七、this is content</p>
10         <p>八、this is content</p>
11         <p>九、this is content</p>
12         <p>十、this is content</p>
13         <p>十一、this is content</p>
14     </div>
15     <div class="bar">
16         <span class="forward"></span>
17         <span class="middle"><em class="scroll"></em></span>
18         <span class="backward"></span>
19     </div>
20 </div>
21 
22 <script type="text/javascript" src="../../lib/seajs/sea.js"></script>
23 <script type="text/javascript" src="../../lib/base/1.0.x/base.js"></script>
24 <script type="text/javascript">
25 seajs.use(['lib/jquery/1.11.x/index.js', '_example/simulationScroll/simulationScroll.js'], function($, scroll) {
26     scroll.init({
27         wapper: $('.wapper'),    
28         distance: 10,
29     });
30 });
View Code

 

js:

  1 //兼容PC移動移動端
  2 define(function(require, exports, module) {
  3 
  4     'use strict';
  5 
  6     var $ = require('lib/jquery/1.11.x/index.js');
  7 
  8     var parameter = null;
  9 
 10     //檢測設備類型
 11     var startWhen, endWhen, moveWhen;
 12     var u = navigator.userAgent; 
 13 
 14     if ( u.match(/\b(Windows\sNT|Macintosh)\b/) ) {
 15         // 鼠標
 16         startWhen = 'mousedown';
 17         endWhen = 'mouseup';
 18         moveWhen = 'mousemove';
 19     } else {
 20         // 觸摸屏
 21         startWhen = 'touchstart';
 22         endWhen = 'touchend';
 23         moveWhen = 'touchmove';
 24     }
 25 
 26     var simulation = {
 27 
 28         _mousedownTimer: 0,
 29         _setintervalId: 0,
 30         _longClick: false,    //是否長點擊
 31         _turnOf: null,    //滾動方向
 32 
 33         init: function(options) {
 34 
 35             var t = this;
 36 
 37             t._scroll = $('.scroll'); //滾動條
 38 
 39             t._wapper = options.wapper.find('.area');    //內容區域
 40             t._distance = options.distance; //點擊上下按鈕頁面每次滾動的距離
 41 
 42             var forward = $('.forward'),
 43                 middle = $('.middle'),
 44                 backward = $('.backward');
 45 
 46             parameter = {
 47                 view: t._wapper.parent().innerHeight(),    //視圖高度
 48                 page: t._wapper.height(),    //內容高度
 49                 barArea: 0,    //滾動條可移動範圍
 50                 scrollHeight: 0,    //滾動條的高度
 51                 scrollDistance: 0    //滾動條每次滾動的距離
 52             };
 53 
 54             //初始化滾動條
 55             if (parameter.page > parameter.view) {
 56 
 57                 //滾動條可移動範圍
 58                 middle.height( parameter.view - forward.height() * 2);
 59 
 60                 parameter.barArea = middle.height();
 61 
 62                 //滾動條高度 = 滾動條可滾動範圍 / (頁面高度 / 可視高度)的百分比
 63                 parameter.scrollHeight = parameter.barArea / (parameter.page / parameter.view) ;
 64                 t._scroll.height(parameter.scrollHeight);
 65 
 66                 //滾動條每次滾動的距離 = 滾動條可移動範圍 * 頁面每次滾動的百分比
 67                 parameter.scrollDistance = parameter.barArea / (parameter.page / t._distance) ;
 68 
 69                 //拖動滾動條
 70                 t.liveEvent();
 71 
 72                 //點擊向前按鈕,若是按下鼠標到鬆開鼠標的時長<100ms,則爲單次點擊
 73                 forward.bind(startWhen, function(e){
 74 
 75                     t._turnOf = 'forward';
 76 
 77                     t.longPress(e, t.direction );
 78 
 79                 }).bind(endWhen, function(e) { 
 80 
 81                     t.mouseupFun(e, t.direction);
 82 
 83                     t._turnOf = null;
 84 
 85                 });
 86 
 87                 //點擊向後按鈕
 88                 backward.bind(startWhen, function(e){
 89 
 90                     t._turnOf = null;
 91 
 92                     t.longPress(e, t.direction );
 93 
 94                 }).bind(endWhen, function(e){
 95 
 96                     t.mouseupFun(e, t.direction );
 97 
 98                 });
 99 
100                 //註冊鼠標滾動事件
101                 // FF
102                 if(document.addEventListener){
103                     document.addEventListener('DOMMouseScroll',t.mouseRuning,false);
104                 }
105 
106                 //其它瀏覽器
107                 document.onmousewheel = t.mouseRuning;
108             }
109         },
110 
111         //鼠標滾動
112         mouseRuning: function(e) {
113 
114             e = e || window.event;
115             var t = simulation;
116             var detail = e.detail || e.wheelDelta;
117 
118             switch(true){
119                 case detail>=100:
120                 case detail<=0 && detail>=-100:
121                     t._turnOf = 'forward';
122                     
123                 break;
124                 
125                 case detail<=-100:
126                 case detail>0 && detail<=100:
127                     t._turnOf = null;
128                 break;
129             }
130 
131             t.direction ();
132         },
133 
134         //判斷是否長點擊
135         longPress: function(e, moveFun ) {
136 
137             var t = this;
138 
139             if ( u.match(/\b(Windows\sNT|Macintosh)\b/) ) {
140                 e = e || window.event;
141 
142                 // 限制爲鼠標左鍵點擊才觸發
143                 if (/^mouse/.test(e.type) && e.which !== 1) {
144                     return;
145                 }
146             }
147 
148             t._setintervalId = setInterval(function(){
149 
150                 t._mousedownTimer += 10;
151 
152                 if( t._mousedownTimer >= 100 ){
153 
154                     moveFun();
155                 }
156 
157             },20);
158         },
159 
160         mouseupFun: function(e, moveFun) {
161             
162             var t = this;
163 
164             if ( u.match(/\b(Windows\sNT|Macintosh)\b/) ) {
165                 e = e || window.event;
166 
167                 // 限制爲鼠標左鍵點擊才觸發
168                 if (/^mouse/.test(e.type) && e.which !== 1) {
169                     return;
170                 }
171             }
172 
173             clearTimeout(t._setintervalId);
174 
175             if( t._mousedownTimer < 100 ) {
176 
177                 moveFun();
178             }
179 
180             t._mousedownTimer = 0;
181         },
182 
183         direction:function() {
184             var t = simulation,
185                 barTop = t._scroll.position().top,
186                 pageTop = t._wapper.position().top,
187                 moveDistance = {};
188 
189                 if ( t._turnOf === 'forward') {
190 
191                     //頁面到頂,不執行任何操做
192                     if (barTop < 0) {
193 
194                         return;
195                     }
196 
197                     moveDistance = {
198                         page: pageTop + t._distance,
199                         bar: barTop - parameter.scrollDistance
200                     }
201 
202                     //若是滾動條距離頂部的距離少 < 每次滾動的距離,或者已經滾動到頂部,則再也不滾動
203                     if(barTop < parameter.scrollDistance || barTop <= 0){
204 
205                         moveDistance = {
206                             page: 0,
207                             bar: 0
208                         }
209                     }
210                 } else {
211 
212                     //頁面到底,不執行任何操做
213                     if (barTop == parameter.barArea - parameter.scrollHeight){
214                         return;
215                     }
216 
217                     moveDistance = {
218                         page: pageTop - t._distance,
219                         bar: barTop + parameter.scrollDistance
220                     };
221 
222                     // 若是滾動條距離底部的距離值 < 每次滾動的距離 或者已經到底部,則一次滾到底
223                     if ( moveDistance.bar + parameter.scrollHeight >= parameter.barArea) {
224 
225                         moveDistance = {
226                             page: parameter.view - parameter.page,
227                             bar: parameter.barArea - parameter.scrollHeight
228                         };
229 
230                     }
231                 }
232 
233                 t._scroll.css({top: moveDistance.bar});
234                 t._wapper.css({top: moveDistance.page});    
235         },
236 
237         //拖動滾動條
238         liveEvent: function() {
239             var t = this,
240                 draging = false,
241                 currentY = 0,
242                 lastY = 0,
243                 pageY = 0;    
244 
245             //檢測設備類型
246             var _ua = function(e) {
247 
248                 var Pos = null;
249 
250                 if ( u.match(/\b(Windows\sNT|Macintosh)\b/) ) {
251                     e = e || window.event;
252 
253                     // 限制爲鼠標左鍵點擊才觸發
254                     if (/^mouse/.test(e.type) && e.which !== 1) {
255                         return;
256                     }
257 
258                     Pos = {
259                         left : e.pageX,
260                         top: e.pageY
261                     }
262 
263                 } else {
264                     Pos = {
265                         left : e.originalEvent.targetTouches[0].pageX,
266                         top: e.originalEvent.targetTouches[0].pageY
267                     }
268                 }
269                 return Pos;
270             };
271 
272             var _start = function(e) {
273 
274                 //監控鼠標
275                 e.preventDefault();
276 
277                 if (t._scroll.get(0).setCapture) {
278                     t._scroll.get(0).setCapture();
279                 }
280 
281                 draging = true;
282 
283                 //記錄當前滾動條的座標
284                 lastY = t._scroll.position().top; 
285 
286                 //記錄按下鼠標的座標
287                 pageY = _ua(e).top;
288             };
289 
290             var _drag = function(e) {
291 
292                 if( draging ) {
293 
294                     var pageTop = t._wapper.position().top;
295                     var barTop = t._scroll.position().top;
296 
297                     //滾動條每移動1px,頁面相對滾動Npx 再 * 當前滾動條的到頂部的距離
298                     var pageMoveDistance = -(parameter.page / (parameter.barArea / 1)) * barTop;
299 
300                     if (lastY + ( _ua(e).top - pageY ) < 0) {
301                         currentY = 0;
302                         pageMoveDistance = 0;
303 
304                     } else if( lastY + ( _ua(e).top - pageY) + parameter.scrollHeight >= parameter.barArea) {
305                         currentY = parameter.barArea - parameter.scrollHeight;
306                         pageMoveDistance = parameter.view - parameter.page;
307                     }
308                     else {
309                         currentY = lastY + ( _ua(e).top - pageY);
310                     }
311 
312                     t._scroll.css({ top:currentY});
313                     t._wapper.css({top: pageMoveDistance});    
314                 }
315             };
316 
317             var _end = function(e) {
318 
319                 if (draging) {
320 
321                     draging = false;
322 
323                     //在IE下釋放對鼠標的控制
324                     if (t._scroll.get(0).setCapture) {
325                         t._scroll.get(0).releaseCapture();
326                     }
327                     
328                     document.onmousemove = null;
329                     document.onmouseup = null;
330                 }
331             };
332 
333             t._scroll.bind( startWhen, _start );
334 
335             t._wapper.bind( startWhen, _start );
336 
337             $(document).bind( moveWhen, _drag );
338            
339             $(document).bind( endWhen, _end );
340 
341             $(document).bind('blur', _end);
342         }
343     }
344     return simulation;
345 });
View Code
相關文章
相關標籤/搜索