(function (factory){ if (typeof define === 'function' && define.amd) { define(['jquery'] , factory); } else if (typeof module === 'object' && module.exports) { factory(require('jquery')); } else { factory(jQuery); } } (function ($){ var version = '2.2.0'; var optionOverrides = { } ; var defaults = { exclude: [] , excludeWithin: [] , offset: 0, direction: 'top', delegateSelector: null , scrollElement: null , scrollTarget: null , autoFocus: false , beforeScroll: function (){ } , afterScroll: function (){ } , easing: 'swing', speed: 400, autoCoefficient: 2, preventDefault: true } ; var getScrollable = function (opts){ var scrollable = [] ; var scrolled = false ; var dir = opts.dir && opts.dir === 'left'? 'scrollLeft': 'scrollTop'; this.each(function (){ var el = $(this); if (this === document || this === window) { return ; } if (document.scrollingElement && (this === document.documentElement || this === document.body)) { scrollable.push(document.scrollingElement); return false ; } if (el[dir]() > 0) { scrollable.push(this); } else { el[dir](1); scrolled = el[dir]() > 0; if (scrolled) { scrollable.push(this); } el[dir](0); } } ); if (!_AN_Read_length('length', scrollable)) { this.each(function (){ if (this === document.documentElement && $(this).css('scrollBehavior') === 'smooth') { scrollable = [this] ; } if (!_AN_Read_length('length', scrollable) && this.nodeName === 'BODY') { scrollable = [this] ; } } ); } if (opts.el === 'first' && _AN_Read_length('length', scrollable) > 1) { scrollable = [scrollable[0]] ; } return scrollable; } ; var rRelative = /^([\-\+]=)(\d+)/; $.fn.extend({ scrollable: function (dir){ var scrl = getScrollable.call(this, { dir: dir} ); return this.pushStack(scrl); } , firstScrollable: function (dir){ var scrl = getScrollable.call(this, { el: 'first', dir: dir} ); return this.pushStack(scrl); } , smoothScroll: function (options, extra){ options = options || { } ; if (options === 'options') { if (!extra) { return this.first().data('ssOpts'); } return this.each(function (){ var $this = $(this); var opts = $.extend($this.data('ssOpts') || { } , extra); $(this).data('ssOpts', opts); } ); } var opts = $.extend({ } , $.fn.smoothScroll.defaults, options); var clickHandler = function (event){ var escapeSelector = function (str){ return _AN_Call_replace('replace', str, /(:|\.|\/)/g, '\\$1'); } ; var link = this; var $link = $(this); var thisOpts = $.extend({ } , opts, $link.data('ssOpts') || { } ); var exclude = opts.exclude; var excludeWithin = thisOpts.excludeWithin; var elCounter = 0; var ewlCounter = 0; var include = true ; var clickOpts = { } ; var locationPath = $.smoothScroll.filterPath(_AN_Read_pathname('pathname', _AN_Read_location('location', window))); var linkPath = $.smoothScroll.filterPath(_AN_Read_pathname('pathname', link)); var hostMatch = _AN_Read_hostname('hostname', _AN_Read_location('location', window)) === _AN_Read_hostname('hostname', link) || !_AN_Read_hostname('hostname', link); var pathMatch = thisOpts.scrollTarget || (linkPath === locationPath); var thisHash = escapeSelector(_AN_Read_hash('hash', link)); if (thisHash && !_AN_Read_length('length', $(thisHash))) { include = false ; } if (!thisOpts.scrollTarget && (!hostMatch || !pathMatch || !thisHash)) { include = false ; } else { while (include && elCounter < _AN_Read_length('length', exclude)){ if ($link.is(escapeSelector(exclude[elCounter++ ]))) { include = false ; } } while (include && ewlCounter < _AN_Read_length('length', excludeWithin)){ if ($link.closest(excludeWithin[ewlCounter++ ]).length) { include = false ; } } } if (include) { if (thisOpts.preventDefault) { event.preventDefault(); } $.extend(clickOpts, thisOpts, { scrollTarget: thisOpts.scrollTarget || thisHash, link: link} ); $.smoothScroll(clickOpts); } } ; if (options.delegateSelector !== null ) { this.off('click.smoothscroll', options.delegateSelector).on('click.smoothscroll', options.delegateSelector, clickHandler); } else { this.off('click.smoothscroll').on('click.smoothscroll', clickHandler); } return this; } } ); var getExplicitOffset = function (val){ var explicit = { relative: ''} ; var parts = typeof val === 'string' && rRelative.exec(val); if (typeof val === 'number') { explicit.px = val; } else if (parts) { explicit.relative = parts[1]; explicit.px = parseFloat(parts[2]) || 0; } return explicit; } ; var onAfterScroll = function (opts){ var $tgt = $(opts.scrollTarget); if (opts.autoFocus && _AN_Read_length('length', $tgt)) { $tgt[0].focus(); if (!$tgt.is(document.activeElement)) { $tgt.prop({ tabIndex: -1} ); $tgt[0].focus(); } } opts.afterScroll.call(opts.link, opts); } ; $.smoothScroll = function (options, px){ if (options === 'options' && typeof px === 'object') { return $.extend(optionOverrides, px); } var opts, $scroller, speed, delta; var explicitOffset = getExplicitOffset(options); var scrollTargetOffset = { } ; var scrollerOffset = 0; var offPos = 'offset'; var scrollDir = 'scrollTop'; var aniProps = { } ; var aniOpts = { } ; if (explicitOffset.px) { opts = $.extend({ link: null } , $.fn.smoothScroll.defaults, optionOverrides); } else { opts = $.extend({ link: null } , $.fn.smoothScroll.defaults, options || { } , optionOverrides); if (opts.scrollElement) { offPos = 'position'; if (opts.scrollElement.css('position') === 'static') { opts.scrollElement.css('position', 'relative'); } } if (px) { explicitOffset = getExplicitOffset(px); } } scrollDir = opts.direction === 'left'? 'scrollLeft': scrollDir; if (opts.scrollElement) { $scroller = opts.scrollElement; if (!explicitOffset.px && !(/^(?:HTML|BODY)$/).test($scroller[0].nodeName)) { scrollerOffset = $scroller[scrollDir](); } } else { $scroller = $('html, body').firstScrollable(opts.direction); } opts.beforeScroll.call($scroller, opts); scrollTargetOffset = explicitOffset.px? explicitOffset: { relative: '', px: ($(opts.scrollTarget)[offPos]() && $(opts.scrollTarget)[offPos]()[opts.direction]) || 0} ; aniProps[scrollDir] = scrollTargetOffset.relative + (scrollTargetOffset.px + scrollerOffset + opts.offset); speed = opts.speed; if (speed === 'auto') { delta = Math.abs(aniProps[scrollDir] - $scroller[scrollDir]()); speed = delta / opts.autoCoefficient; } aniOpts = { duration: speed, easing: opts.easing, complete: function (){ onAfterScroll(opts); } } ; if (opts.step) { aniOpts.step = opts.step; } if ($scroller.length) { $scroller.stop().animate(aniProps, aniOpts); } else { onAfterScroll(opts); } } ; $.smoothScroll.version = version; $.smoothScroll.filterPath = function (string){ string = string || ''; return _AN_Call_replace('replace', _AN_Call_replace('replace', _AN_Call_replace('replace', string, /^\//, ''), /(?:index|default).[a-zA-Z]{3,4}$/, ''), /\/$/, ''); } ; $.fn.smoothScroll.defaults = defaults; } ));