Subversion Repositories Integrator Subversion

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 espaco 1
/*! Copyright (c) 2011 Piotr Rochala (http://rocha.la)
2
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
3
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
4
 *
5
 * Improved by keenthemes for Metronic Theme
6
 * Version: 1.3.2
7
 *
8
 */
9
(function($) {
10
 
11
    jQuery.fn.extend({
12
        slimScroll: function(options) {
13
 
14
            var defaults = {
15
 
16
                // width in pixels of the visible scroll area
17
                width: 'auto',
18
 
19
                // height in pixels of the visible scroll area
20
                height: '250px',
21
 
22
                // width in pixels of the scrollbar and rail
23
                size: '7px',
24
 
25
                // scrollbar color, accepts any hex/color value
26
                color: '#000',
27
 
28
                // scrollbar position - left/right
29
                position: 'right',
30
 
31
                // distance in pixels between the side edge and the scrollbar
32
                distance: '1px',
33
 
34
                // default scroll position on load - top / bottom / $('selector')
35
                start: 'top',
36
 
37
                // sets scrollbar opacity
38
                opacity: .4,
39
 
40
                // enables always-on mode for the scrollbar
41
                alwaysVisible: false,
42
 
43
                // check if we should hide the scrollbar when user is hovering over
44
                disableFadeOut: false,
45
 
46
                // sets visibility of the rail
47
                railVisible: false,
48
 
49
                // sets rail color
50
                railColor: '#333',
51
 
52
                // sets rail opacity
53
                railOpacity: .2,
54
 
55
                // whether  we should use jQuery UI Draggable to enable bar dragging
56
                railDraggable: true,
57
 
58
                // defautlt CSS class of the slimscroll rail
59
                railClass: 'slimScrollRail',
60
 
61
                // defautlt CSS class of the slimscroll bar
62
                barClass: 'slimScrollBar',
63
 
64
                // defautlt CSS class of the slimscroll wrapper
65
                wrapperClass: 'slimScrollDiv',
66
 
67
                // check if mousewheel should scroll the window if we reach top/bottom
68
                allowPageScroll: false,
69
 
70
                // scroll amount applied to each mouse wheel step
71
                wheelStep: 20,
72
 
73
                // scroll amount applied when user is using gestures
74
                touchScrollStep: 200,
75
 
76
                // sets border radius
77
                borderRadius: '7px',
78
 
79
                // sets border radius of the rail
80
                railBorderRadius: '7px',
81
 
82
                // sets animation status on a given scroll(added my keenthemes)
83
                animate: true
84
            };
85
 
86
            var o = $.extend(defaults, options);
87
 
88
            // do it for every element that matches selector
89
            this.each(function() {
90
 
91
                var isOverPanel, isOverBar, isDragg, queueHide, touchDif,
92
                    barHeight, percentScroll, lastScroll,
93
                    divS = '<div></div>',
94
                    minBarHeight = 30,
95
                    releaseScroll = false;
96
 
97
                // used in event handlers and for better minification
98
                var me = $(this);
99
 
100
                //begin: windows phone fix added by keenthemes
101
                if ('ontouchstart' in window && window.navigator.msPointerEnabled) {
102
                  me.css("-ms-touch-action", "none");
103
              }
104
                //end: windows phone fix added by keenthemes
105
 
106
                // ensure we are not binding it again
107
                if (me.parent().hasClass(o.wrapperClass)) {
108
                    // start from last bar position
109
                    var offset = me.scrollTop();
110
 
111
                    // find bar and rail
112
                    bar = me.parent().find('.' + o.barClass);
113
                    rail = me.parent().find('.' + o.railClass);
114
 
115
                    getBarHeight();
116
 
117
                    // check if we should scroll existing instance
118
                    if ($.isPlainObject(options)) {
119
                        // Pass height: auto to an existing slimscroll object to force a resize after contents have changed
120
                        if ('height' in options && options.height == 'auto') {
121
                            me.parent().css('height', 'auto');
122
                            me.css('height', 'auto');
123
                            var height = me.parent().parent().height();
124
                            me.parent().css('height', height);
125
                            me.css('height', height);
126
                        }
127
 
128
                        if ('scrollTo' in options) {
129
                            // jump to a static point
130
                            offset = parseInt(o.scrollTo);
131
                        } else if ('scrollBy' in options) {
132
                            // jump by value pixels
133
                            offset += parseInt(o.scrollBy);
134
                        } else if ('destroy' in options) {
135
                            // remove slimscroll elements
136
                            bar.remove();
137
                            rail.remove();
138
                            me.unwrap();
139
                            return;
140
                        }
141
 
142
                        // scroll content by the given offset
143
                        scrollContent(offset, false, true);
144
                    }
145
 
146
                    return;
147
                }
148
 
149
                // optionally set height to the parent's height
150
                o.height = (options.height == 'auto') ? me.parent().height() : options.height;
151
 
152
                // wrap content
153
                var wrapper = $(divS)
154
                    .addClass(o.wrapperClass)
155
                    .css({
156
                        position: 'relative',
157
                        overflow: 'hidden',
158
                        width: o.width,
159
                        height: o.height
160
                    });
161
 
162
                // update style for the div
163
                me.css({
164
                    overflow: 'hidden',
165
                    width: o.width,
166
                    height: o.height
167
                });
168
 
169
                // create scrollbar rail
170
                var rail = $(divS)
171
                    .addClass(o.railClass)
172
                    .css({
173
                        width: o.size,
174
                        height: '100%',
175
                        position: 'absolute',
176
                        top: 0,
177
                        display: (o.alwaysVisible && o.railVisible) ? 'block' : 'none',
178
                        'border-radius': o.railBorderRadius,
179
                        background: o.railColor,
180
                        opacity: o.railOpacity,
181
                        zIndex: 90
182
                    });
183
 
184
                // create scrollbar
185
                var bar = $(divS)
186
                    .addClass(o.barClass)
187
                    .css({
188
                        background: o.color,
189
                        width: o.size,
190
                        position: 'absolute',
191
                        top: 0,
192
                        opacity: o.opacity,
193
                        display: o.alwaysVisible ? 'block' : 'none',
194
                        'border-radius': o.borderRadius,
195
                        BorderRadius: o.borderRadius,
196
                        MozBorderRadius: o.borderRadius,
197
                        WebkitBorderRadius: o.borderRadius,
198
                        zIndex: 99
199
                    });
200
 
201
                // set position
202
                var posCss = (o.position == 'right') ? {
203
                    right: o.distance
204
                } : {
205
                    left: o.distance
206
                };
207
                rail.css(posCss);
208
                bar.css(posCss);
209
 
210
                // wrap it
211
                me.wrap(wrapper);
212
 
213
                // append to parent div
214
                me.parent().append(bar);
215
                me.parent().append(rail);
216
 
217
                // make it draggable and no longer dependent on the jqueryUI
218
                if (o.railDraggable) {
219
                    bar.bind("mousedown", function(e) {
220
                        var $doc = $(document);
221
                        isDragg = true;
222
                        t = parseFloat(bar.css('top'));
223
                        pageY = e.pageY;
224
 
225
                        $doc.bind("mousemove.slimscroll", function(e) {
226
                            currTop = t + e.pageY - pageY;
227
                            bar.css('top', currTop);
228
                            scrollContent(0, bar.position().top, false); // scroll content
229
                        });
230
 
231
                        $doc.bind("mouseup.slimscroll", function(e) {
232
                            isDragg = false;
233
                            hideBar();
234
                            $doc.unbind('.slimscroll');
235
                        });
236
                        return false;
237
                    }).bind("selectstart.slimscroll", function(e) {
238
                        e.stopPropagation();
239
                        e.preventDefault();
240
                        return false;
241
                    });
242
                }
243
 
244
                //begin: windows phone fix added by keenthemes
245
                if ('ontouchstart' in window && window.navigator.msPointerEnabled) {
246
                    me.bind('MSPointerDown', function(e, b) {
247
                        // record where touch started
248
                        touchDif = e.originalEvent.pageY;
249
                    });
250
 
251
                    me.bind('MSPointerMove', function(e) {
252
                        // prevent scrolling the page if necessary
253
                        e.originalEvent.preventDefault();
254
                        // see how far user swiped
255
                        var diff = (touchDif - e.originalEvent.pageY) / o.touchScrollStep;
256
                        // scroll content
257
                        scrollContent(diff, true);
258
                        touchDif = e.originalEvent.pageY;
259
                    });
260
                }
261
                //end: windows phone fix added by keenthemes
262
 
263
                // on rail over
264
                rail.hover(function() {
265
                    showBar();
266
                }, function() {
267
                    hideBar();
268
                });
269
 
270
                // on bar over
271
                bar.hover(function() {
272
                    isOverBar = true;
273
                }, function() {
274
                    isOverBar = false;
275
                });
276
 
277
                // show on parent mouseover
278
                me.hover(function() {
279
                    isOverPanel = true;
280
                    showBar();
281
                    hideBar();
282
                }, function() {
283
                    isOverPanel = false;
284
                    hideBar();
285
                });
286
 
287
                // support for mobile
288
                me.bind('touchstart', function(e, b) {
289
                    if (e.originalEvent.touches.length) {
290
                        // record where touch started
291
                        touchDif = e.originalEvent.touches[0].pageY;
292
                    }
293
                });
294
 
295
                me.bind('touchmove', function(e) {
296
                    // prevent scrolling the page if necessary
297
                    if (!releaseScroll) {
298
                        e.originalEvent.preventDefault();
299
                    }
300
                    if (e.originalEvent.touches.length) {
301
                        // see how far user swiped
302
                        var diff = (touchDif - e.originalEvent.touches[0].pageY) / o.touchScrollStep;
303
                        // scroll content
304
                        scrollContent(diff, true);
305
                        touchDif = e.originalEvent.touches[0].pageY;
306
                    }
307
                });
308
 
309
                // set up initial height
310
                getBarHeight();
311
 
312
                // check start position
313
                if (o.start === 'bottom') {
314
                    // scroll content to bottom
315
                    bar.css({
316
                        top: me.outerHeight() - bar.outerHeight()
317
                    });
318
                    scrollContent(0, true);
319
                } else if (o.start !== 'top') {
320
                    // assume jQuery selector
321
                    scrollContent($(o.start).position().top, null, true);
322
 
323
                    // make sure bar stays hidden
324
                    if (!o.alwaysVisible) {
325
                        bar.hide();
326
                    }
327
                }
328
 
329
                // attach scroll events
330
                attachWheel();
331
 
332
                function _onWheel(e) {
333
                    // use mouse wheel only when mouse is over
334
                    if (!isOverPanel) {
335
                        return;
336
                    }
337
 
338
                    var e = e || window.event;
339
 
340
                    var delta = 0;
341
                    if (e.wheelDelta) {
342
                        delta = -e.wheelDelta / 120;
343
                    }
344
                    if (e.detail) {
345
                        delta = e.detail / 3;
346
                    }
347
 
348
                    var target = e.target || e.srcTarget || e.srcElement;
349
                    if ($(target).closest('.' + o.wrapperClass).is(me.parent())) {
350
                        // scroll content
351
                        scrollContent(delta, true);
352
                    }
353
 
354
                    // stop window scroll
355
                    if (e.preventDefault && !releaseScroll) {
356
                        e.preventDefault();
357
                    }
358
                    if (!releaseScroll) {
359
                        e.returnValue = false;
360
                    }
361
                }
362
 
363
                function scrollContent(y, isWheel, isJump) {
364
                    releaseScroll = false;
365
                    var delta = y;
366
                    var maxTop = me.outerHeight() - bar.outerHeight();
367
 
368
                    if (isWheel) {
369
                        // move bar with mouse wheel
370
                        delta = parseInt(bar.css('top')) + y * parseInt(o.wheelStep) / 100 * bar.outerHeight();
371
 
372
                        // move bar, make sure it doesn't go out
373
                        delta = Math.min(Math.max(delta, 0), maxTop);
374
 
375
                        // if scrolling down, make sure a fractional change to the
376
                        // scroll position isn't rounded away when the scrollbar's CSS is set
377
                        // this flooring of delta would happened automatically when
378
                        // bar.css is set below, but we floor here for clarity
379
                        delta = (y > 0) ? Math.ceil(delta) : Math.floor(delta);
380
 
381
                        // scroll the scrollbar
382
                        bar.css({
383
                            top: delta + 'px'
384
                        });
385
                    }
386
 
387
                    // calculate actual scroll amount
388
                    percentScroll = parseInt(bar.css('top')) / (me.outerHeight() - bar.outerHeight());
389
                    delta = percentScroll * (me[0].scrollHeight - me.outerHeight());
390
 
391
                    if (isJump) {
392
                        delta = y;
393
                        var offsetTop = delta / me[0].scrollHeight * me.outerHeight();
394
                        offsetTop = Math.min(Math.max(offsetTop, 0), maxTop);
395
                        bar.css({
396
                            top: offsetTop + 'px'
397
                        });
398
                    }
399
 
400
                    // scroll content
401
                    if ('scrollTo' in o && o.animate) {
402
                        me.animate({
403
                            scrollTop: delta
404
                        });
405
                    } else {
406
                        me.scrollTop(delta);
407
                    }
408
 
409
                    // fire scrolling event
410
                    me.trigger('slimscrolling', ~~delta);
411
 
412
                    // ensure bar is visible
413
                    showBar();
414
 
415
                    // trigger hide when scroll is stopped
416
                    hideBar();
417
 
418
                }
419
 
420
                function attachWheel() {
421
                    if (window.addEventListener) {
422
                        this.addEventListener('DOMMouseScroll', _onWheel, false);
423
                        this.addEventListener('mousewheel', _onWheel, false);
424
                    } else {
425
                        document.attachEvent("onmousewheel", _onWheel)
426
                    }
427
                }
428
 
429
                function getBarHeight() {
430
                    // calculate scrollbar height and make sure it is not too small
431
                    barHeight = Math.max((me.outerHeight() / me[0].scrollHeight) * me.outerHeight(), minBarHeight);
432
                    bar.css({
433
                        height: barHeight + 'px'
434
                    });
435
 
436
                    // hide scrollbar if content is not long enough
437
                    var display = barHeight == me.outerHeight() ? 'none' : 'block';
438
                    bar.css({
439
                        display: display
440
                    });
441
                }
442
 
443
                function showBar() {
444
                    // recalculate bar height
445
                    getBarHeight();
446
                    clearTimeout(queueHide);
447
 
448
                    // when bar reached top or bottom
449
                    if (percentScroll == ~~percentScroll) {
450
                        //release wheel
451
                        releaseScroll = o.allowPageScroll;
452
 
453
                        // publish approporiate event
454
                        if (lastScroll != percentScroll) {
455
                            var msg = (~~percentScroll == 0) ? 'top' : 'bottom';
456
                            me.trigger('slimscroll', msg);
457
                        }
458
                    } else {
459
                        releaseScroll = false;
460
                    }
461
                    lastScroll = percentScroll;
462
 
463
                    // show only when required
464
                    if (barHeight >= me.outerHeight()) {
465
                        //allow window scroll
466
                        releaseScroll = true;
467
                        return;
468
                    }
469
                    bar.stop(true, true).fadeIn('fast');
470
                    if (o.railVisible) {
471
                        rail.stop(true, true).fadeIn('fast');
472
                    }
473
                }
474
 
475
                function hideBar() {
476
                    // only hide when options allow it
477
                    if (!o.alwaysVisible) {
478
                        queueHide = setTimeout(function() {
479
                            if (!(o.disableFadeOut && isOverPanel) && !isOverBar && !isDragg) {
480
                                bar.fadeOut('slow');
481
                                rail.fadeOut('slow');
482
                            }
483
                        }, 1000);
484
                    }
485
                }
486
 
487
            });
488
 
489
            // maintain chainability
490
            return this;
491
        }
492
    });
493
 
494
    jQuery.fn.extend({
495
        slimscroll: jQuery.fn.slimScroll
496
    });
497
 
498
})(jQuery);