diff --git a/index.html b/index.html index 5fcc3f2..12d8220 100644 --- a/index.html +++ b/index.html @@ -77,10 +77,10 @@

Smooth Scroll Plugin

NPM

Download

Using npm:

-
1
npm install jquery-smooth-scroll
+
1
npm install jquery-smooth-scroll

Using bower:

-
1
bower install jquery-smooth-scroll
+
1
bower install jquery-smooth-scroll

The old-fashioned way:

Go to the following URL in your browser and copy/paste the code into your own file: @@ -99,7 +99,7 @@

$.fn.smoothScroll

Options

The following options, shown with their default values, are available for both $.fn.smoothScroll and $.smoothScroll:

-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
  offset: 0,
 
  // one of 'top' or 'left'
  direction: 'top',
 
  // only use if you want to override default behavior
  scrollTarget: null,
 
  // fn(opts) function to be called before scrolling occurs.
  // `this` is the element(s) being scrolled
  beforeScroll: function() {},
 
  // fn(opts) function to be called after scrolling occurs.
  // `this` is the triggering element
  afterScroll: function() {},
  easing: 'swing',
 
  // speed can be a number or 'auto'
  // if 'auto', the speed will be calculated based on the formula:
  // (current scroll position - target scroll position) / autoCoeffic
  speed: 400,
 
  // autoCoefficent: Only used when speed set to "auto".
  // The higher this number, the faster the scroll speed
  autoCoefficient: 2,
 
  // $.fn.smoothScroll only: whether to prevent the default click action
  preventDefault: true
 
}
+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
  offset: 0,
 
  // one of 'top' or 'left'
  direction: 'top',
 
  // only use if you want to override default behavior
  scrollTarget: null,
 
  // fn(opts) function to be called before scrolling occurs.
  // `this` is the element(s) being scrolled
  beforeScroll: function() {},
 
  // fn(opts) function to be called after scrolling occurs.
  // `this` is the triggering element
  afterScroll: function() {},
  easing: 'swing',
 
  // speed can be a number or 'auto'
  // if 'auto', the speed will be calculated based on the formula:
  // (current scroll position - target scroll position) / autoCoeffic
  speed: 400,
 
  // autoCoefficent: Only used when speed set to "auto".
  // The higher this number, the faster the scroll speed
  autoCoefficient: 2,
 
  // $.fn.smoothScroll only: whether to prevent the default click action
  preventDefault: true
 
}

The options object for $.fn.smoothScroll can take two additional properties: exclude and excludeWithin. The value for both of these is an array of @@ -116,7 +116,7 @@

$.smoothScroll

document.body)
  • Doesn't automatically fire, so you need to bind it to some other user interaction. For example:

    -
    1
    2
    3
    4
    5
    6
    7
    $('button.scrollsomething').on('click', function() {
      $.smoothScroll({
        scrollElement: $('div.scrollme'),
        scrollTarget: '#findme'
      });
      return false;
    });
    +
    1
    2
    3
    4
    5
    6
    7
    $('button.scrollsomething').on('click', function() {
      $.smoothScroll({
        scrollElement: $('div.scrollme'),
        scrollTarget: '#findme'
      });
      return false;
    });
  • The $.smoothScroll method can take one or two arguments.

      @@ -130,7 +130,7 @@

      $.smoothScroll

      Additional Option

      The following option, in addition to those listed for $.fn.smoothScroll above, is available for $.smoothScroll:

      -
      1
      2
      3
      4
      5
      {
        // jQuery set of elements you wish to scroll.
        //  if null (default), $('html, body').firstScrollable() is used.
        scrollElement: null
      }
      +
      1
      2
      3
      4
      5
      {
        // jQuery set of elements you wish to scroll.
        //  if null (default), $('html, body').firstScrollable() is used.
        scrollElement: null
      }

      $.fn.scrollable

        diff --git a/jquery.smooth-scroll.js b/jquery.smooth-scroll.js index 0ecc899..478f4fd 100644 --- a/jquery.smooth-scroll.js +++ b/jquery.smooth-scroll.js @@ -1,5 +1,5 @@ /*! - * jQuery Smooth Scroll - v1.5.5 - 2015-02-19 + * jQuery Smooth Scroll - v1.5.5 - 2015-03-03 * https://github.com/kswedberg/jquery-smooth-scroll * Copyright (c) 2015 Karl Swedberg * Licensed MIT (https://github.com/kswedberg/jquery-smooth-scroll/blob/master/LICENSE-MIT) @@ -129,9 +129,6 @@ var link = this, $link = $(this), thisOpts = $.extend({}, opts, $link.data('ssOpts') || {}), - exclude = opts.exclude, - excludeWithin = thisOpts.excludeWithin, - elCounter = 0, ewlCounter = 0, include = true, clickOpts = {}, hostMatch = ((location.hostname === link.hostname) || !link.hostname), @@ -140,17 +137,6 @@ if ( !thisOpts.scrollTarget && (!hostMatch || !pathMatch || !thisHash) ) { include = false; - } else { - while (include && elCounter < exclude.length) { - if ($link.is(escapeSelector(exclude[elCounter++]))) { - include = false; - } - } - while ( include && ewlCounter < excludeWithin.length ) { - if ($link.closest(excludeWithin[ewlCounter++]).length) { - include = false; - } - } } if ( include ) { @@ -176,7 +162,9 @@ if ( options === 'options' && typeof px === 'object' ) { return $.extend(optionOverrides, px); } - var opts, $scroller, scrollTargetOffset, speed, delta, + var opts, $scroller, scrollTargetOffset, speed, delta, $target, + targetExcluded = false, + elCounter = 0, ewlCounter = 0, scrollerOffset = 0, offPos = 'offset', scrollDir = 'scrollTop', @@ -196,59 +184,73 @@ } } - scrollDir = opts.direction === 'left' ? 'scrollLeft' : scrollDir; - - if ( opts.scrollElement ) { - $scroller = opts.scrollElement; - if ( !(/^(?:HTML|BODY)$/).test($scroller[0].nodeName) ) { - scrollerOffset = $scroller[scrollDir](); + $target = $(opts.scrollTarget); + while (!targetExcluded && elCounter < opts.exclude.length) { + if ($target.is(escapeSelector(opts.exclude[elCounter++]))) { + targetExcluded = true; + } + } + while ( !targetExcluded && ewlCounter < opts.excludeWithin.length ) { + if ($target.closest(opts.excludeWithin[ewlCounter++]).length) { + targetExcluded = true; } - } else { - $scroller = $('html, body').firstScrollable(opts.direction); } - // beforeScroll callback function must fire before calculating offset - opts.beforeScroll.call($scroller, opts); + if ( !targetExcluded ) { + scrollDir = opts.direction === 'left' ? 'scrollLeft' : scrollDir; - scrollTargetOffset = (typeof options === 'number') ? options : - px || - ( $(opts.scrollTarget)[offPos]() && - $(opts.scrollTarget)[offPos]()[opts.direction] ) || - 0; + if ( opts.scrollElement ) { + $scroller = opts.scrollElement; + if ( !(/^(?:HTML|BODY)$/).test($scroller[0].nodeName) ) { + scrollerOffset = $scroller[scrollDir](); + } + } else { + $scroller = $('html, body').firstScrollable(opts.direction); + } - aniProps[scrollDir] = scrollTargetOffset + scrollerOffset + opts.offset; - speed = opts.speed; + // beforeScroll callback function must fire before calculating offset + opts.beforeScroll.call($scroller, opts); - // automatically calculate the speed of the scroll based on distance / coefficient - if (speed === 'auto') { + scrollTargetOffset = (typeof options === 'number') ? options : + px || + ( $(opts.scrollTarget)[offPos]() && + $(opts.scrollTarget)[offPos]()[opts.direction] ) || + 0; - // $scroller.scrollTop() is position before scroll, aniProps[scrollDir] is position after - // When delta is greater, speed will be greater. - delta = aniProps[scrollDir] - $scroller.scrollTop(); - if(delta < 0) { - delta *= -1; - } + aniProps[scrollDir] = scrollTargetOffset + scrollerOffset + opts.offset; + speed = opts.speed; - // Divide the delta by the coefficient - speed = delta / opts.autoCoefficient; - } + // automatically calculate the speed of the scroll based on distance / coefficient + if (speed === 'auto') { - aniOpts = { - duration: speed, - easing: opts.easing, - complete: function() { - opts.afterScroll.call(opts.link, opts); + // $scroller.scrollTop() is position before scroll, aniProps[scrollDir] is position after + // When delta is greater, speed will be greater. + delta = aniProps[scrollDir] - $scroller.scrollTop(); + if(delta < 0) { + delta *= -1; + } + + // Divide the delta by the coefficient + speed = delta / opts.autoCoefficient; } - }; - if (opts.step) { - aniOpts.step = opts.step; - } + aniOpts = { + duration: speed, + easing: opts.easing, + complete: function() { + opts.afterScroll.call(opts.link, opts); + } + }; - if ($scroller.length) { - $scroller.stop().animate(aniProps, aniOpts); - } else { - opts.afterScroll.call(opts.link, opts); + if (opts.step) { + aniOpts.step = opts.step; + } + + if ($scroller.length) { + $scroller.stop().animate(aniProps, aniOpts); + } else { + opts.afterScroll.call(opts.link, opts); + } } }; diff --git a/jquery.smooth-scroll.min.js b/jquery.smooth-scroll.min.js index a2b55a5..3ab340b 100644 --- a/jquery.smooth-scroll.min.js +++ b/jquery.smooth-scroll.min.js @@ -1,7 +1,7 @@ /*! - * jQuery Smooth Scroll - v1.5.5 - 2015-02-19 + * jQuery Smooth Scroll - v1.5.5 - 2015-03-03 * https://github.com/kswedberg/jquery-smooth-scroll * Copyright (c) 2015 Karl Swedberg * Licensed MIT (https://github.com/kswedberg/jquery-smooth-scroll/blob/master/LICENSE-MIT) */ -(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&module.exports?t(require("jquery")):t(jQuery)})(function(t){function e(t){return t.replace(/(:|\.|\/)/g,"\\$1")}var l="1.5.5",o={},n={exclude:[],excludeWithin:[],offset:0,direction:"top",scrollElement:null,scrollTarget:null,beforeScroll:function(){},afterScroll:function(){},easing:"swing",speed:400,autoCoefficient:2,preventDefault:!0},s=function(e){var l=[],o=!1,n=e.dir&&"left"===e.dir?"scrollLeft":"scrollTop";return this.each(function(){if(this!==document&&this!==window){var e=t(this);e[n]()>0?l.push(this):(e[n](1),o=e[n]()>0,o&&l.push(this),e[n](0))}}),l.length||this.each(function(){"BODY"===this.nodeName&&(l=[this])}),"first"===e.el&&l.length>1&&(l=[l[0]]),l};t.fn.extend({scrollable:function(t){var e=s.call(this,{dir:t});return this.pushStack(e)},firstScrollable:function(t){var e=s.call(this,{el:"first",dir:t});return this.pushStack(e)},smoothScroll:function(l,o){if(l=l||{},"options"===l)return o?this.each(function(){var e=t(this),l=t.extend(e.data("ssOpts")||{},o);t(this).data("ssOpts",l)}):this.first().data("ssOpts");var n=t.extend({},t.fn.smoothScroll.defaults,l),s=t.smoothScroll.filterPath(location.pathname);return this.unbind("click.smoothscroll").bind("click.smoothscroll",function(l){var o=this,r=t(this),i=t.extend({},n,r.data("ssOpts")||{}),c=n.exclude,a=i.excludeWithin,f=0,h=0,u=!0,d={},p=location.hostname===o.hostname||!o.hostname,m=i.scrollTarget||t.smoothScroll.filterPath(o.pathname)===s,S=e(o.hash);if(i.scrollTarget||p&&m&&S){for(;u&&c.length>f;)r.is(e(c[f++]))&&(u=!1);for(;u&&a.length>h;)r.closest(a[h++]).length&&(u=!1)}else u=!1;u&&(i.preventDefault&&l.preventDefault(),t.extend(d,i,{scrollTarget:i.scrollTarget||S,link:o}),t.smoothScroll(d))}),this}}),t.smoothScroll=function(e,l){if("options"===e&&"object"==typeof l)return t.extend(o,l);var n,s,r,i,c,a=0,f="offset",h="scrollTop",u={},d={};"number"==typeof e?(n=t.extend({link:null},t.fn.smoothScroll.defaults,o),r=e):(n=t.extend({link:null},t.fn.smoothScroll.defaults,e||{},o),n.scrollElement&&(f="position","static"===n.scrollElement.css("position")&&n.scrollElement.css("position","relative"))),h="left"===n.direction?"scrollLeft":h,n.scrollElement?(s=n.scrollElement,/^(?:HTML|BODY)$/.test(s[0].nodeName)||(a=s[h]())):s=t("html, body").firstScrollable(n.direction),n.beforeScroll.call(s,n),r="number"==typeof e?e:l||t(n.scrollTarget)[f]()&&t(n.scrollTarget)[f]()[n.direction]||0,u[h]=r+a+n.offset,i=n.speed,"auto"===i&&(c=u[h]-s.scrollTop(),0>c&&(c*=-1),i=c/n.autoCoefficient),d={duration:i,easing:n.easing,complete:function(){n.afterScroll.call(n.link,n)}},n.step&&(d.step=n.step),s.length?s.stop().animate(u,d):n.afterScroll.call(n.link,n)},t.smoothScroll.version=l,t.smoothScroll.filterPath=function(t){return t=t||"",t.replace(/^\//,"").replace(/(?:index|default).[a-zA-Z]{3,4}$/,"").replace(/\/$/,"")},t.fn.smoothScroll.defaults=n}); \ No newline at end of file +(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&module.exports?t(require("jquery")):t(jQuery)})(function(t){function e(t){return t.replace(/(:|\.|\/)/g,"\\$1")}var l="1.5.5",o={},n={exclude:[],excludeWithin:[],offset:0,direction:"top",scrollElement:null,scrollTarget:null,beforeScroll:function(){},afterScroll:function(){},easing:"swing",speed:400,autoCoefficient:2,preventDefault:!0},r=function(e){var l=[],o=!1,n=e.dir&&"left"===e.dir?"scrollLeft":"scrollTop";return this.each(function(){if(this!==document&&this!==window){var e=t(this);e[n]()>0?l.push(this):(e[n](1),o=e[n]()>0,o&&l.push(this),e[n](0))}}),l.length||this.each(function(){"BODY"===this.nodeName&&(l=[this])}),"first"===e.el&&l.length>1&&(l=[l[0]]),l};t.fn.extend({scrollable:function(t){var e=r.call(this,{dir:t});return this.pushStack(e)},firstScrollable:function(t){var e=r.call(this,{el:"first",dir:t});return this.pushStack(e)},smoothScroll:function(l,o){if(l=l||{},"options"===l)return o?this.each(function(){var e=t(this),l=t.extend(e.data("ssOpts")||{},o);t(this).data("ssOpts",l)}):this.first().data("ssOpts");var n=t.extend({},t.fn.smoothScroll.defaults,l),r=t.smoothScroll.filterPath(location.pathname);return this.unbind("click.smoothscroll").bind("click.smoothscroll",function(l){var o=this,s=t(this),i=t.extend({},n,s.data("ssOpts")||{}),c=!0,a={},f=location.hostname===o.hostname||!o.hostname,h=i.scrollTarget||t.smoothScroll.filterPath(o.pathname)===r,u=e(o.hash);i.scrollTarget||f&&h&&u||(c=!1),c&&(i.preventDefault&&l.preventDefault(),t.extend(a,i,{scrollTarget:i.scrollTarget||u,link:o}),t.smoothScroll(a))}),this}}),t.smoothScroll=function(l,n){if("options"===l&&"object"==typeof n)return t.extend(o,n);var r,s,i,c,a,f,h=!1,u=0,d=0,p=0,m="offset",S="scrollTop",g={},x={};for("number"==typeof l?(r=t.extend({link:null},t.fn.smoothScroll.defaults,o),i=l):(r=t.extend({link:null},t.fn.smoothScroll.defaults,l||{},o),r.scrollElement&&(m="position","static"===r.scrollElement.css("position")&&r.scrollElement.css("position","relative"))),f=t(r.scrollTarget);!h&&r.exclude.length>u;)f.is(e(r.exclude[u++]))&&(h=!0);for(;!h&&r.excludeWithin.length>d;)f.closest(r.excludeWithin[d++]).length&&(h=!0);h||(S="left"===r.direction?"scrollLeft":S,r.scrollElement?(s=r.scrollElement,/^(?:HTML|BODY)$/.test(s[0].nodeName)||(p=s[S]())):s=t("html, body").firstScrollable(r.direction),r.beforeScroll.call(s,r),i="number"==typeof l?l:n||t(r.scrollTarget)[m]()&&t(r.scrollTarget)[m]()[r.direction]||0,g[S]=i+p+r.offset,c=r.speed,"auto"===c&&(a=g[S]-s.scrollTop(),0>a&&(a*=-1),c=a/r.autoCoefficient),x={duration:c,easing:r.easing,complete:function(){r.afterScroll.call(r.link,r)}},r.step&&(x.step=r.step),s.length?s.stop().animate(g,x):r.afterScroll.call(r.link,r))},t.smoothScroll.version=l,t.smoothScroll.filterPath=function(t){return t=t||"",t.replace(/^\//,"").replace(/(?:index|default).[a-zA-Z]{3,4}$/,"").replace(/\/$/,"")},t.fn.smoothScroll.defaults=n}); \ No newline at end of file diff --git a/src/jquery.smooth-scroll.js b/src/jquery.smooth-scroll.js index 28ac4db..66a4eaf 100644 --- a/src/jquery.smooth-scroll.js +++ b/src/jquery.smooth-scroll.js @@ -110,9 +110,6 @@ var link = this, $link = $(this), thisOpts = $.extend({}, opts, $link.data('ssOpts') || {}), - exclude = opts.exclude, - excludeWithin = thisOpts.excludeWithin, - elCounter = 0, ewlCounter = 0, include = true, clickOpts = {}, hostMatch = ((location.hostname === link.hostname) || !link.hostname), @@ -121,17 +118,6 @@ if ( !thisOpts.scrollTarget && (!hostMatch || !pathMatch || !thisHash) ) { include = false; - } else { - while (include && elCounter < exclude.length) { - if ($link.is(escapeSelector(exclude[elCounter++]))) { - include = false; - } - } - while ( include && ewlCounter < excludeWithin.length ) { - if ($link.closest(excludeWithin[ewlCounter++]).length) { - include = false; - } - } } if ( include ) { @@ -157,7 +143,9 @@ if ( options === 'options' && typeof px === 'object' ) { return $.extend(optionOverrides, px); } - var opts, $scroller, scrollTargetOffset, speed, delta, + var opts, $scroller, scrollTargetOffset, speed, delta, $target, + targetExcluded = false, + elCounter = 0, ewlCounter = 0, scrollerOffset = 0, offPos = 'offset', scrollDir = 'scrollTop', @@ -177,59 +165,73 @@ } } - scrollDir = opts.direction === 'left' ? 'scrollLeft' : scrollDir; - - if ( opts.scrollElement ) { - $scroller = opts.scrollElement; - if ( !(/^(?:HTML|BODY)$/).test($scroller[0].nodeName) ) { - scrollerOffset = $scroller[scrollDir](); + $target = $(opts.scrollTarget); + while (!targetExcluded && elCounter < opts.exclude.length) { + if ($target.is(escapeSelector(opts.exclude[elCounter++]))) { + targetExcluded = true; + } + } + while ( !targetExcluded && ewlCounter < opts.excludeWithin.length ) { + if ($target.closest(opts.excludeWithin[ewlCounter++]).length) { + targetExcluded = true; } - } else { - $scroller = $('html, body').firstScrollable(opts.direction); } - // beforeScroll callback function must fire before calculating offset - opts.beforeScroll.call($scroller, opts); + if ( !targetExcluded ) { + scrollDir = opts.direction === 'left' ? 'scrollLeft' : scrollDir; - scrollTargetOffset = (typeof options === 'number') ? options : - px || - ( $(opts.scrollTarget)[offPos]() && - $(opts.scrollTarget)[offPos]()[opts.direction] ) || - 0; + if ( opts.scrollElement ) { + $scroller = opts.scrollElement; + if ( !(/^(?:HTML|BODY)$/).test($scroller[0].nodeName) ) { + scrollerOffset = $scroller[scrollDir](); + } + } else { + $scroller = $('html, body').firstScrollable(opts.direction); + } - aniProps[scrollDir] = scrollTargetOffset + scrollerOffset + opts.offset; - speed = opts.speed; + // beforeScroll callback function must fire before calculating offset + opts.beforeScroll.call($scroller, opts); - // automatically calculate the speed of the scroll based on distance / coefficient - if (speed === 'auto') { + scrollTargetOffset = (typeof options === 'number') ? options : + px || + ( $(opts.scrollTarget)[offPos]() && + $(opts.scrollTarget)[offPos]()[opts.direction] ) || + 0; - // $scroller.scrollTop() is position before scroll, aniProps[scrollDir] is position after - // When delta is greater, speed will be greater. - delta = aniProps[scrollDir] - $scroller.scrollTop(); - if(delta < 0) { - delta *= -1; - } + aniProps[scrollDir] = scrollTargetOffset + scrollerOffset + opts.offset; + speed = opts.speed; - // Divide the delta by the coefficient - speed = delta / opts.autoCoefficient; - } + // automatically calculate the speed of the scroll based on distance / coefficient + if (speed === 'auto') { - aniOpts = { - duration: speed, - easing: opts.easing, - complete: function() { - opts.afterScroll.call(opts.link, opts); + // $scroller.scrollTop() is position before scroll, aniProps[scrollDir] is position after + // When delta is greater, speed will be greater. + delta = aniProps[scrollDir] - $scroller.scrollTop(); + if(delta < 0) { + delta *= -1; + } + + // Divide the delta by the coefficient + speed = delta / opts.autoCoefficient; } - }; - if (opts.step) { - aniOpts.step = opts.step; - } + aniOpts = { + duration: speed, + easing: opts.easing, + complete: function() { + opts.afterScroll.call(opts.link, opts); + } + }; - if ($scroller.length) { - $scroller.stop().animate(aniProps, aniOpts); - } else { - opts.afterScroll.call(opts.link, opts); + if (opts.step) { + aniOpts.step = opts.step; + } + + if ($scroller.length) { + $scroller.stop().animate(aniProps, aniOpts); + } else { + opts.afterScroll.call(opts.link, opts); + } } };