PageSourceSearch

https://cndrussian.com/themes/contrib/zetraz/assets/js/jquery.smooth-scroll.js?v=8.x

js cndrussian.com collected 2026-10-06 08:53:44 UTC 7,201 bytes, 252 lines download raw bytes

1(function($) {
2var version = '1.5.2',
3    optionOverrides = {},
4    defaults = {
5      exclude: [],
6      excludeWithin:[],
7      offset: 0,
8
9      // one of 'top' or 'left'
10      direction: 'top',
11
12      // jQuery set of elements you wish to scroll (for $.smoothScroll).
13      //  if null (default), $('html, body').firstScrollable() is used.
14      scrollElement: null,
15
16      // only use if you want to override default behavior
17      scrollTarget: null,
18
19      // fn(opts) function to be called before scrolling occurs.
20      // `this` is the element(s) being scrolled
21      beforeScroll: function() {},
22
23      // fn(opts) function to be called after scrolling occurs.
24      // `this` is the triggering element
25      afterScroll: function() {},
26      easing: 'swing',
27      speed: 400,
28
29      // coefficient for "auto" speed
30      autoCoefficient: 2,
31
32      // $.fn.smoothScroll only: whether to prevent the default click action
33      preventDefault: true
34    },
35
36    getScrollable = function(opts) {
37      var scrollable = [],
38          scrolled = false,
39          dir = opts.dir && opts.dir === 'left' ? 'scrollLeft' : 'scrollTop';
40
41      this.each(function() {
42
43        if (this === document || this === window) { return; }
44        var el = $(this);
45        if ( el[dir]() > 0 ) {
46          scrollable.push(this);
47        } else {
48          // if scroll(Top|Left) === 0, nudge the element 1px and see if it moves
49          el[dir](1);
50          scrolled = el[dir]() > 0;
51          if ( scrolled ) {
52            scrollable.push(this);
53          }
54          // then put it back, of course
55          el[dir](0);
56        }
57      });
58
59      // If no scrollable elements, fall back to <body>,
60      // if it's in the jQuery collection
61      // (doing this because Safari sets scrollTop async,
62      // so can't set it to 1 and immediately get the value.)
63      if (!scrollable.length) {
64        this.each(function() {
65          if (this.nodeName === 'BODY') {
66            scrollable = [this];
67          }
68        });
69      }
70
71      // Use the first scrollable element if we're calling firstScrollable()
72      if ( opts.el === 'first' && scrollable.length > 1 ) {
73        scrollable = [ scrollable[0] ];
74      }
75
76      return scrollable;
77    };
78
79$.fn.extend({
80  scrollable: function(dir) {
81    var scrl = getScrollable.call(this, {dir: dir});
82    return this.pushStack(scrl);
83  },
84  firstScrollable: function(dir) {
85    var scrl = getScrollable.call(this, {el: 'first', dir: dir});
86    return this.pushStack(scrl);
87  },
88
89  smoothScroll: function(options, extra) {
90    options = options || {};
91
92    if ( options === 'options' ) {
93      if ( !extra ) {
94        return this.first().data('ssOpts');
95      }
96      return this.each(function() {
97        var $this = $(this),
98            opts = $.extend($this.data('ssOpts') || {}, extra);
99
100        $(this).data('ssOpts', opts);
101      });
102    }
103
104    var opts = $.extend({}, $.fn.smoothScroll.defaults, options),
105        locationPath = $.smoothScroll.filterPath(location.pathname);
106
107    this
108    .unbind('click.smoothscroll')
109    .bind('click.smoothscroll', function(event) {
110      var link = this,
111          $link = $(this),
112          thisOpts = $.extend({}, opts, $link.data('ssOpts') || {}),
113          exclude = opts.exclude,
114          excludeWithin = thisOpts.excludeWithin,
115          elCounter = 0, ewlCounter = 0,
116          include = true,
117          clickOpts = {},
118          hostMatch = ((location.hostname === link.hostname) || !link.hostname),
119          pathMatch = thisOpts.scrollTarget || ( $.smoothScroll.filterPath(link.pathname) === locationPath ),
120          thisHash = escapeSelector(link.hash);
121
122      if ( !thisOpts.scrollTarget && (!hostMatch || !pathMatch || !thisHash) ) {
123        include = false;
124      } else {
125        while (include && elCounter < exclude.length) {
126          if ($link.is(escapeSelector(exclude[elCounter++]))) {
127            include = false;
128          }
129        }
130        while ( include && ewlCounter < excludeWithin.length ) {
131          if ($link.closest(excludeWithin[ewlCounter++]).length) {
132            include = false;
133          }
134        }
135      }
136
137      if ( include ) {
138
139        if ( thisOpts.preventDefault ) {
140          event.preventDefault();
141        }
142
143        $.extend( clickOpts, thisOpts, {
144          scrollTarget: thisOpts.scrollTarget || thisHash,
145          link: link
146        });
147
148        $.smoothScroll( clickOpts );
149      }
150    });
151
152    return this;
153  }
154});
155
156$.smoothScroll = function(options, px) {
157  if ( options === 'options' && typeof px === 'object' ) {
158    return $.extend(optionOverrides, px);
159  }
160  var opts, $scroller, scrollTargetOffset, speed, delta,
161      scrollerOffset = 0,
162      offPos = 'offset',
163      scrollDir = 'scrollTop',
164      aniProps = {},
165      aniOpts = {};
166
167  if (typeof options === 'number') {
168    opts = $.extend({link: null}, $.fn.smoothScroll.defaults, optionOverrides);
169    scrollTargetOffset = options;
170  } else {
171    opts = $.extend({link: null}, $.fn.smoothScroll.defaults, options || {}, optionOverrides);
172    if (opts.scrollElement) {
173      offPos = 'position';
174      if (opts.scrollElement.css('position') === 'static') {
175        opts.scrollElement.css('position', 'relative');
176      }
177    }
178  }
179
180  scrollDir = opts.direction === 'left' ? 'scrollLeft' : scrollDir;
181
182  if ( opts.scrollElement ) {
183    $scroller = opts.scrollElement;
184    if ( !(/^(?:HTML|BODY)$/).test($scroller[0].nodeName) ) {
185      scrollerOffset = $scroller[scrollDir]();
186    }
187  } else {
188    $scroller = $('html, body').firstScrollable(opts.direction);
189  }
190
191  // beforeScroll callback function must fire before calculating offset
192  opts.beforeScroll.call($scroller, opts);
193
194  scrollTargetOffset = (typeof options === 'number') ? options :
195                        px ||
196                        ( $(opts.scrollTarget)[offPos]() &&
197                        $(opts.scrollTarget)[offPos]()[opts.direction] ) ||
198                        0;
199
200  aniProps[scrollDir] = scrollTargetOffset + scrollerOffset + opts.offset;
201  speed = opts.speed;
202
203  // automatically calculate the speed of the scroll based on distance / coefficient
204  if (speed === 'auto') {
205
206    // $scroller.scrollTop() is position before scroll, aniProps[scrollDir] is position after
207    // When delta is greater, speed will be greater.
208    delta = aniProps[scrollDir] - $scroller.scrollTop();
209    if(delta < 0) {
210      delta *= -1;
211    }
212
213    // Divide the delta by the coefficient
214    speed = delta / opts.autoCoefficient;
215  }
216
217  aniOpts = {
218    duration: speed,
219    easing: opts.easing,
220    complete: function() {
221      opts.afterScroll.call(opts.link, opts);
222    }
223  };
224
225  if (opts.step) {
226    aniOpts.step = opts.step;
227  }
228
229  if ($scroller.length) {
230    $scroller.stop().animate(aniProps, aniOpts);
231  } else {
232    opts.afterScroll.call(opts.link, opts);
233  }
234};
235
236$.smoothScroll.version = version;
237$.smoothScroll.filterPath = function(string) {
238  string = string || '';
239  return string
240    .replace(/^\//,'')
241    .replace(/(?:index|default).[a-zA-Z]{3,4}$/,'')
242    .replace(/\/$/,'');
243};
244
245// default options
246$.fn.smoothScroll.defaults = defaults;
247
248function escapeSelector (str) {
249  return str.replace(/(:|\.)/g,'\\$1');
250}
251
252})(jQuery);

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.