PageSourceSearch

http://dmradio-bijeljina.com/js/jquery.nanoscroller.js

js dmradio-bijeljina.com collected 2026-10-08 10:15:28 UTC 19,488 bytes, 768 lines download raw bytes

1/*! nanoScrollerJS - v0.7.2
2* http://jamesflorentino.github.com/nanoScrollerJS/
3* Copyright (c) 2013 James Florentino; Licensed MIT */
4
5
6(function($, window, document) {
7  "use strict";
8
9  var BROWSER_IS_IE7, BROWSER_SCROLLBAR_WIDTH, DOMSCROLL, DOWN, DRAG, KEYDOWN, KEYUP, MOUSEDOWN, MOUSEMOVE, MOUSEUP, MOUSEWHEEL, NanoScroll, PANEDOWN, RESIZE, SCROLL, SCROLLBAR, TOUCHMOVE, UP, WHEEL, defaults, getBrowserScrollbarWidth;
10  defaults = {
11    /**
12      a classname for the pane element.
13      @property paneClass
14      @type String
15      @default 'pane'
16    */
17
18    paneClass: 'pane',
19    /**
20      a classname for the slider element.
21      @property sliderClass
22      @type String
23      @default 'slider'
24    */
25
26    sliderClass: 'slider',
27    /**
28      a classname for the content element.
29      @property contentClass
30      @type String
31      @default 'content'
32    */
33
34    contentClass: 'content',
35    /**
36      a setting to enable native scrolling in iOS devices.
37      @property iOSNativeScrolling
38      @type Boolean
39      @default false
40    */
41
42    iOSNativeScrolling: false,
43    /**
44      a setting to prevent the rest of the page being
45      scrolled when user scrolls the `.content` element.
46      @property preventPageScrolling
47      @type Boolean
48      @default false
49    */
50
51    preventPageScrolling: false,
52    /**
53      a setting to disable binding to the resize event.
54      @property disableResize
55      @type Boolean
56      @default false
57    */
58
59    disableResize: false,
60    /**
61      a setting to make the scrollbar always visible.
62      @property alwaysVisible
63      @type Boolean
64      @default false
65    */
66
67    alwaysVisible: false,
68    /**
69      a default timeout for the `flash()` method.
70      @property flashDelay
71      @type Number
72      @default 1500
73    */
74
75    flashDelay: 1500,
76    /**
77      a minimum height for the `.slider` element.
78      @property sliderMinHeight
79      @type Number
80      @default 20
81    */
82
83    sliderMinHeight: 20,
84    /**
85      a maximum height for the `.slider` element.
86      @property sliderMaxHeight
87      @type Number
88      @default null
89    */
90
91    sliderMaxHeight: null,
92    /**
93      an alternate document context.
94      @property documentContext
95      @type Document
96      @default null
97    */
98
99    documentContext: null,
100    /**
101      an alternate window context.
102      @property windowContext
103      @type Window
104      @default null
105    */
106
107    windowContext: null
108  };
109  /**
110    @property SCROLLBAR
111    @type String
112    @static
113    @final
114    @private
115  */
116
117  SCROLLBAR = 'scrollbar';
118  /**
119    @property SCROLL
120    @type String
121    @static
122    @final
123    @private
124  */
125
126  SCROLL = 'scroll';
127  /**
128    @property MOUSEDOWN
129    @type String
130    @final
131    @private
132  */
133
134  MOUSEDOWN = 'mousedown';
135  /**
136    @property MOUSEMOVE
137    @type String
138    @static
139    @final
140    @private
141  */
142
143  MOUSEMOVE = 'mousemove';
144  /**
145    @property MOUSEWHEEL
146    @type String
147    @final
148    @private
149  */
150
151  MOUSEWHEEL = 'mousewheel';
152  /**
153    @property MOUSEUP
154    @type String
155    @static
156    @final
157    @private
158  */
159
160  MOUSEUP = 'mouseup';
161  /**
162    @property RESIZE
163    @type String
164    @final
165    @private
166  */
167
168  RESIZE = 'resize';
169  /**
170    @property DRAG
171    @type String
172    @static
173    @final
174    @private
175  */
176
177  DRAG = 'drag';
178  /**
179    @property UP
180    @type String
181    @static
182    @final
183    @private
184  */
185
186  UP = 'up';
187  /**
188    @property PANEDOWN
189    @type String
190    @static
191    @final
192    @private
193  */
194
195  PANEDOWN = 'panedown';
196  /**
197    @property DOMSCROLL
198    @type String
199    @static
200    @final
201    @private
202  */
203
204  DOMSCROLL = 'DOMMouseScroll';
205  /**
206    @property DOWN
207    @type String
208    @static
209    @final
210    @private
211  */
212
213  DOWN = 'down';
214  /**
215    @property WHEEL
216    @type String
217    @static
218    @final
219    @private
220  */
221
222  WHEEL = 'wheel';
223  /**
224    @property KEYDOWN
225    @type String
226    @static
227    @final
228    @private
229  */
230
231  KEYDOWN = 'keydown';
232  /**
233    @property KEYUP
234    @type String
235    @static
236    @final
237    @private
238  */
239
240  KEYUP = 'keyup';
241  /**
242    @property TOUCHMOVE
243    @type String
244    @static
245    @final
246    @private
247  */
248
249  TOUCHMOVE = 'touchmove';
250  /**
251    @property BROWSER_IS_IE7
252    @type Boolean
253    @static
254    @final
255    @private
256  */
257
258  BROWSER_IS_IE7 = window.navigator.appName === 'Microsoft Internet Explorer' && /msie 7./i.test(window.navigator.appVersion) && window.ActiveXObject;
259  /**
260    @property BROWSER_SCROLLBAR_WIDTH
261    @type Number
262    @static
263    @default null
264    @private
265  */
266
267  BROWSER_SCROLLBAR_WIDTH = null;
268  /**
269    Returns browser's native scrollbar width
270    @method getBrowserScrollbarWidth
271    @return {Number} the scrollbar width in pixels
272    @static
273    @private
274  */
275
276  getBrowserScrollbarWidth = function() {
277    var outer, outerStyle, scrollbarWidth;
278    outer = document.createElement('div');
279    outerStyle = outer.style;
280    outerStyle.position = 'absolute';
281    outerStyle.width = '100px';
282    outerStyle.height = '100px';
283    outerStyle.overflow = SCROLL;
284    outerStyle.top = '-9999px';
285    document.body.appendChild(outer);
286    scrollbarWidth = outer.offsetWidth - outer.clientWidth;
287    document.body.removeChild(outer);
288    return scrollbarWidth;
289  };
290  /**
291    @class NanoScroll
292    @param element {HTMLElement|Node} the main element
293    @param options {Object} nanoScroller's options
294    @constructor
295  */
296
297  NanoScroll = (function() {
298
299    function NanoScroll(el, options) {
300      this.el = el;
301      this.options = options;
302      BROWSER_SCROLLBAR_WIDTH || (BROWSER_SCROLLBAR_WIDTH = getBrowserScrollbarWidth());
303      this.$el = $(this.el);
304      this.doc = $(this.options.documentContext || document);
305      this.win = $(this.options.windowContext || window);
306      this.$content = this.$el.children("." + options.contentClass);
307      this.$content.attr('tabindex', 0);
308      this.content = this.$content[0];
309      if (this.options.iOSNativeScrolling && (this.el.style.WebkitOverflowScrolling != null)) {
310        this.nativeScrolling();
311      } else {
312        this.generate();
313      }
314      this.createEvents();
315      this.addEvents();
316      this.reset();
317    }
318
319    /**
320      Prevents the rest of the page being scrolled
321      when user scrolls the `.content` element.
322      @method preventScrolling
323      @param event {Event}
324      @param direction {String} Scroll direction (up or down)
325      @private
326    */
327
328
329    NanoScroll.prototype.preventScrolling = function(e, direction) {
330      if (!this.isActive) {
331        return;
332      }
333      if (e.type === DOMSCROLL) {
334        if (direction === DOWN && e.originalEvent.detail > 0 || direction === UP && e.originalEvent.detail < 0) {
335          e.preventDefault();
336        }
337      } else if (e.type === MOUSEWHEEL) {
338        if (!e.originalEvent || !e.originalEvent.wheelDelta) {
339          return;
340        }
341        if (direction === DOWN && e.originalEvent.wheelDelta < 0 || direction === UP && e.originalEvent.wheelDelta > 0) {
342          e.preventDefault();
343        }
344      }
345    };
346
347    /**
348      Enable iOS native scrolling
349    */
350
351
352    NanoScroll.prototype.nativeScrolling = function() {
353      this.$content.css({
354        WebkitOverflowScrolling: 'touch'
355      });
356      this.iOSNativeScrolling = true;
357      this.isActive = true;
358    };
359
360    /**
361      Updates those nanoScroller properties that
362      are related to current scrollbar position.
363      @method updateScrollValues
364      @private
365    */
366
367
368    NanoScroll.prototype.updateScrollValues = function() {
369      var content;
370      content = this.content;
371      this.maxScrollTop = content.scrollHeight - content.clientHeight;
372      this.contentScrollTop = content.scrollTop;
373      if (!this.iOSNativeScrolling) {
374        this.maxSliderTop = this.paneHeight - this.sliderHeight;
375        this.sliderTop = this.contentScrollTop * this.maxSliderTop / this.maxScrollTop;
376      }
377    };
378
379    /**
380      Creates event related methods
381      @method createEvents
382      @private
383    */
384
385
386    NanoScroll.prototype.createEvents = function() {
387      var _this = this;
388      this.events = {
389        down: function(e) {
390          _this.isBeingDragged = true;
391          _this.offsetY = e.pageY - _this.slider.offset().top;
392          _this.pane.addClass('active');
393          _this.doc.bind(MOUSEMOVE, _this.events[DRAG]).bind(MOUSEUP, _this.events[UP]);
394          return false;
395        },
396        drag: function(e) {
397          _this.sliderY = e.pageY - _this.$el.offset().top - _this.offsetY;
398          _this.scroll();
399          _this.updateScrollValues();
400          if (_this.contentScrollTop >= _this.maxScrollTop) {
401            _this.$el.trigger('scrollend');
402          } else if (_this.contentScrollTop === 0) {
403            _this.$el.trigger('scrolltop');
404          }
405          return false;
406        },
407        up: function(e) {
408          _this.isBeingDragged = false;
409          _this.pane.removeClass('active');
410          _this.doc.unbind(MOUSEMOVE, _this.events[DRAG]).unbind(MOUSEUP, _this.events[UP]);
411          return false;
412        },
413        resize: function(e) {
414          _this.reset();
415        },
416        panedown: function(e) {
417          _this.sliderY = (e.offsetY || e.originalEvent.layerY) - (_this.sliderHeight * 0.5);
418          _this.scroll();
419          _this.events.down(e);
420          return false;
421        },
422        scroll: function(e) {
423          if (_this.isBeingDragged) {
424            return;
425          }
426          _this.updateScrollValues();
427          if (!_this.iOSNativeScrolling) {
428            _this.sliderY = _this.sliderTop;
429            _this.slider.css({
430              top: _this.sliderTop
431            });
432          }
433          if (e == null) {
434            return;
435          }
436          if (_this.contentScrollTop >= _this.maxScrollTop) {
437            if (_this.options.preventPageScrolling) {
438              _this.preventScrolling(e, DOWN);
439            }
440            _this.$el.trigger('scrollend');
441          } else if (_this.contentScrollTop === 0) {
442            if (_this.options.preventPageScrolling) {
443              _this.preventScrolling(e, UP);
444            }
445            _this.$el.trigger('scrolltop');
446          }
447        },
448        wheel: function(e) {
449          if (e == null) {
450            return;
451          }
452          _this.sliderY += -e.wheelDeltaY || -e.delta;
453          _this.scroll();
454          return false;
455        }
456      };
457    };
458
459    /**
460      Adds event listeners with jQuery.
461      @method addEvents
462      @private
463    */
464
465
466    NanoScroll.prototype.addEvents = function() {
467      var events;
468      this.removeEvents();
469      events = this.events;
470      if (!this.options.disableResize) {
471        this.win.bind(RESIZE, events[RESIZE]);
472      }
473      if (!this.iOSNativeScrolling) {
474        this.slider.bind(MOUSEDOWN, events[DOWN]);
475        this.pane.bind(MOUSEDOWN, events[PANEDOWN]).bind("" + MOUSEWHEEL + " " + DOMSCROLL, events[WHEEL]);
476      }
477      this.$content.bind("" + SCROLL + " " + MOUSEWHEEL + " " + DOMSCROLL + " " + TOUCHMOVE, events[SCROLL]);
478    };
479
480    /**
481      Removes event listeners with jQuery.
482      @method removeEvents
483      @private
484    */
485
486
487    NanoScroll.prototype.removeEvents = function() {
488      var events;
489      events = this.events;
490      this.win.unbind(RESIZE, events[RESIZE]);
491      if (!this.iOSNativeScrolling) {
492        this.slider.unbind();
493        this.pane.unbind();
494      }
495      this.$content.unbind("" + SCROLL + " " + MOUSEWHEEL + " " + DOMSCROLL + " " + TOUCHMOVE, events[SCROLL]);
496    };
497
498    /**
499      Generates nanoScroller's scrollbar and elements for it.
500      @method generate
501      @chainable
502      @private
503    */
504
505
506    NanoScroll.prototype.generate = function() {
507      var contentClass, cssRule, options, paneClass, sliderClass;
508      options = this.options;
509      paneClass = options.paneClass, sliderClass = options.sliderClass, contentClass = options.contentClass;
510      if (!this.$el.find("" + paneClass).length && !this.$el.find("" + sliderClass).length) {
511        this.$el.append("<div class=\"" + paneClass + "\"><div class=\"" + sliderClass + "\" /></div>");
512      }
513      this.pane = this.$el.children("." + paneClass);
514      this.slider = this.pane.find("." + sliderClass);
515      if (BROWSER_SCROLLBAR_WIDTH) {
516        cssRule = this.$el.css('direction') === 'rtl' ? {
517          left: -BROWSER_SCROLLBAR_WIDTH
518        } : {
519          right: -BROWSER_SCROLLBAR_WIDTH
520        };
521        this.$el.addClass('has-scrollbar');
522      }
523      if (cssRule != null) {
524        this.$content.css(cssRule);
525      }
526      return this;
527    };
528
529    /**
530      @method restore
531      @private
532    */
533
534
535    NanoScroll.prototype.restore = function() {
536      this.stopped = false;
537      this.pane.show();
538      this.addEvents();
539    };
540
541    /**
542      Resets nanoScroller's scrollbar.
543      @method reset
544      @chainable
545      @example
546          $(".nano").nanoScroller();
547    */
548
549
550    NanoScroll.prototype.reset = function() {
551      var content, contentHeight, contentStyle, contentStyleOverflowY, paneBottom, paneHeight, paneOuterHeight, paneTop, sliderHeight;
552      if (this.iOSNativeScrolling) {
553        this.contentHeight = this.content.scrollHeight;
554        return;
555      }
556      if (!this.$el.find("." + this.options.paneClass).length) {
557        this.generate().stop();
558      }
559      if (this.stopped) {
560        this.restore();
561      }
562      content = this.content;
563      contentStyle = content.style;
564      contentStyleOverflowY = contentStyle.overflowY;
565      if (BROWSER_IS_IE7) {
566        this.$content.css({
567          height: this.$content.height()
568        });
569      }
570      contentHeight = content.scrollHeight + BROWSER_SCROLLBAR_WIDTH;
571      paneHeight = this.pane.outerHeight();
572      paneTop = parseInt(this.pane.css('top'), 10);
573      paneBottom = parseInt(this.pane.css('bottom'), 10);
574      paneOuterHeight = paneHeight + paneTop + paneBottom;
575      sliderHeight = Math.round(paneOuterHeight / contentHeight * paneOuterHeight);
576      if (sliderHeight < this.options.sliderMinHeight) {
577        sliderHeight = this.options.sliderMinHeight;
578      } else if ((this.options.sliderMaxHeight != null) && sliderHeight > this.options.sliderMaxHeight) {
579        sliderHeight = this.options.sliderMaxHeight;
580      }
581      if (contentStyleOverflowY === SCROLL && contentStyle.overflowX !== SCROLL) {
582        sliderHeight += BROWSER_SCROLLBAR_WIDTH;
583      }
584      this.maxSliderTop = paneOuterHeight - sliderHeight;
585      this.contentHeight = contentHeight;
586      this.paneHeight = paneHeight;
587      this.paneOuterHeight = paneOuterHeight;
588      this.sliderHeight = sliderHeight;
589      this.slider.height(sliderHeight);
590      this.events.scroll();
591      this.pane.show();
592      this.isActive = true;
593      if ((content.scrollHeight === content.clientHeight) || (this.pane.outerHeight(true) >= content.scrollHeight && contentStyleOverflowY !== SCROLL)) {
594        this.pane.hide();
595        this.isActive = false;
596      } else if (this.el.clientHeight === content.scrollHeight && contentStyleOverflowY === SCROLL) {
597        this.slider.hide();
598      } else {
599        this.slider.show();
600      }
601      this.pane.css({
602        opacity: (this.options.alwaysVisible ? 1 : ''),
603        visibility: (this.options.alwaysVisible ? 'visible' : '')
604      });
605      return this;
606    };
607
608    /**
609      @method scroll
610      @private
611      @example
612          $(".nano").nanoScroller({ scroll: 'top' });
613    */
614
615
616    NanoScroll.prototype.scroll = function() {
617      if (!this.isActive) {
618        return;
619      }
620      this.sliderY = Math.max(0, this.sliderY);
621      this.sliderY = Math.min(this.maxSliderTop, this.sliderY);
622      this.$content.scrollTop((this.paneHeight - this.contentHeight + BROWSER_SCROLLBAR_WIDTH) * this.sliderY / this.maxSliderTop * -1);
623      if (!this.iOSNativeScrolling) {
624        this.slider.css({
625          top: this.sliderY
626        });
627      }
628      return this;
629    };
630
631    /**
632      Scroll at the bottom with an offset value
633      @method scrollBottom
634      @param offsetY {Number}
635      @chainable
636      @example
637          $(".nano").nanoScroller({ scrollBottom: value });
638    */
639
640
641    NanoScroll.prototype.scrollBottom = function(offsetY) {
642      if (!this.isActive) {
643        return;
644      }
645      this.reset();
646      this.$content.scrollTop(this.contentHeight - this.$content.height() - offsetY).trigger(MOUSEWHEEL);
647      return this;
648    };
649
650    /**
651      Scroll at the top with an offset value
652      @method scrollTop
653      @param offsetY {Number}
654      @chainable
655      @example
656          $(".nano").nanoScroller({ scrollTop: value });
657    */
658
659
660    NanoScroll.prototype.scrollTop = function(offsetY) {
661      if (!this.isActive) {
662        return;
663      }
664      this.reset();
665      this.$content.scrollTop(+offsetY).trigger(MOUSEWHEEL);
666      return this;
667    };
668
669    /**
670      Scroll to an element
671      @method scrollTo
672      @param node {Node} A node to scroll to.
673      @chainable
674      @example
675          $(".nano").nanoScroller({ scrollTo: $('#a_node') });
676    */
677
678
679    NanoScroll.prototype.scrollTo = function(node) {
680      if (!this.isActive) {
681        return;
682      }
683      this.reset();
684      this.scrollTop($(node).get(0).offsetTop);
685      return this;
686    };
687
688    /**
689      To stop the operation.
690      This option will tell the plugin to disable all event bindings and hide the gadget scrollbar from the UI.
691      @method stop
692      @chainable
693      @example
694          $(".nano").nanoScroller({ stop: true });
695    */
696
697
698    NanoScroll.prototype.stop = function() {
699      this.stopped = true;
700      this.removeEvents();
701      this.pane.hide();
702      return this;
703    };
704
705    /**
706      To flash the scrollbar gadget for an amount of time defined in plugin settings (defaults to 1,5s).
707      Useful if you want to show the user (e.g. on pageload) that there is more content waiting for him.
708      @method flash
709      @chainable
710      @example
711          $(".nano").nanoScroller({ flash: true });
712    */
713
714
715    NanoScroll.prototype.flash = function() {
716      var _this = this;
717      if (!this.isActive) {
718        return;
719      }
720      this.reset();
721      this.pane.addClass('flashed');
722      setTimeout(function() {
723        _this.pane.removeClass('flashed');
724      }, this.options.flashDelay);
725      return this;
726    };
727
728    return NanoScroll;
729
730  })();
731  $.fn.nanoScroller = function(settings) {
732    return this.each(function() {
733      var options, scrollbar;
734      if (!(scrollbar = this.nanoscroller)) {
735        options = $.extend({}, defaults, settings);
736        this.nanoscroller = scrollbar = new NanoScroll(this, options);
737      }
738      if (settings && typeof settings === "object") {
739        $.extend(scrollbar.options, settings);
740        if (settings.scrollBottom) {
741          return scrollbar.scrollBottom(settings.scrollBottom);
742        }
743        if (settings.scrollTop) {
744          return scrollbar.scrollTop(settings.scrollTop);
745        }
746        if (settings.scrollTo) {
747          return scrollbar.scrollTo(settings.scrollTo);
748        }
749        if (settings.scroll === 'bottom') {
750          return scrollbar.scrollBottom(0);
751        }
752        if (settings.scroll === 'top') {
753          return scrollbar.scrollTop(0);
754        }
755        if (settings.scroll && settings.scroll instanceof $) {
756          return scrollbar.scrollTo(settings.scroll);
757        }
758        if (settings.stop) {
759          return scrollbar.stop();
760        }
761        if (settings.flash) {
762          return scrollbar.flash();
763        }
764      }
765      return scrollbar.reset();
766    });
767  };
768})(jQuery, window, document);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.