relatively-sticky

A jQuery plugin for creating smart sticky elements
git clone https://git.ce9e.org/relatively-sticky.git

commit
8b77aa0e5ca868dcbb830f8d1dae8a0bfc8b9ad3
parent
2ee6fe30473e263183b34f7a30c01574474094e8
Author
leaf corcoran <leafot@gmail.com>
Date
2014-11-11 22:20
add option to disable bottoming

Diffstat

M jquery.sticky-kit.coffee 35 +++++++++++++++++++++++------------
M jquery.sticky-kit.js 27 ++++++++++++++++-----------
M jquery.sticky-kit.min.js 10 +++++-----

3 files changed, 44 insertions, 28 deletions


diff --git a/jquery.sticky-kit.coffee b/jquery.sticky-kit.coffee

@@ -6,12 +6,22 @@ $ = @jQuery or window.jQuery
    6     6 
    7     7 win = $ window
    8     8 $.fn.stick_in_parent = (opts={}) ->
    9    -1   { sticky_class, inner_scrolling, parent: parent_selector, offset_top, spacer: manual_spacer } = opts
   -1     9   {
   -1    10     sticky_class
   -1    11     inner_scrolling
   -1    12     parent: parent_selector
   -1    13     offset_top
   -1    14     spacer: manual_spacer
   -1    15     bottoming: enable_bottoming
   -1    16   } = opts
   -1    17 
   10    18   offset_top ?= 0
   11    19   parent_selector ?= undefined
   12    20   inner_scrolling ?= true
   13    21   sticky_class ?= "is_stuck"
   14    22 
   -1    23   enable_bottoming = true unless enable_bottoming?
   -1    24 
   15    25   for elm in @
   16    26     ((elm, padding_bottom, parent_top, parent_height, top, height, el_float) ->
   17    27       return if elm.data "sticky_kit"
@@ -84,16 +94,17 @@ $.fn.stick_in_parent = (opts={}) ->
   84    94         last_pos = scroll
   85    95 
   86    96         if fixed
   87    -1           will_bottom = scroll + height + offset > parent_height + parent_top
   88    -1 
   89    -1           # unbottom
   90    -1           if bottomed && !will_bottom
   91    -1             bottomed = false
   92    -1             elm.css({
   93    -1               position: "fixed"
   94    -1               bottom: ""
   95    -1               top: offset
   96    -1             }).trigger("sticky_kit:unbottom")
   -1    97           if enable_bottoming
   -1    98             will_bottom = scroll + height + offset > parent_height + parent_top
   -1    99 
   -1   100             # unbottom
   -1   101             if bottomed && !will_bottom
   -1   102               bottomed = false
   -1   103               elm.css({
   -1   104                 position: "fixed"
   -1   105                 bottom: ""
   -1   106                 top: offset
   -1   107               }).trigger("sticky_kit:unbottom")
   97   108 
   98   109           # unfixing
   99   110           if scroll < top
@@ -153,7 +164,7 @@ $.fn.stick_in_parent = (opts={}) ->
  153   164 
  154   165         # this is down here because we can fix and bottom in same step when
  155   166         # scrolling huge
  156    -1         if fixed
   -1   167         if fixed && enable_bottoming
  157   168           will_bottom ?= scroll + height + offset > parent_height + parent_top
  158   169 
  159   170           # bottomed

diff --git a/jquery.sticky-kit.js b/jquery.sticky-kit.js

@@ -12,11 +12,11 @@
   12    12   win = $(window);
   13    13 
   14    14   $.fn.stick_in_parent = function(opts) {
   15    -1     var elm, inner_scrolling, manual_spacer, offset_top, parent_selector, sticky_class, _fn, _i, _len;
   -1    15     var elm, enable_bottoming, inner_scrolling, manual_spacer, offset_top, parent_selector, sticky_class, _fn, _i, _len;
   16    16     if (opts == null) {
   17    17       opts = {};
   18    18     }
   19    -1     sticky_class = opts.sticky_class, inner_scrolling = opts.inner_scrolling, parent_selector = opts.parent, offset_top = opts.offset_top, manual_spacer = opts.spacer;
   -1    19     sticky_class = opts.sticky_class, inner_scrolling = opts.inner_scrolling, parent_selector = opts.parent, offset_top = opts.offset_top, manual_spacer = opts.spacer, enable_bottoming = opts.bottoming;
   20    20     if (offset_top == null) {
   21    21       offset_top = 0;
   22    22     }
@@ -29,6 +29,9 @@
   29    29     if (sticky_class == null) {
   30    30       sticky_class = "is_stuck";
   31    31     }
   -1    32     if (enable_bottoming == null) {
   -1    33       enable_bottoming = true;
   -1    34     }
   32    35     _fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float) {
   33    36       var bottomed, detach, fixed, last_pos, offset, parent, recalc, recalc_and_tick, spacer, tick;
   34    37       if (elm.data("sticky_kit")) {
@@ -100,14 +103,16 @@
  100   103         }
  101   104         last_pos = scroll;
  102   105         if (fixed) {
  103    -1           will_bottom = scroll + height + offset > parent_height + parent_top;
  104    -1           if (bottomed && !will_bottom) {
  105    -1             bottomed = false;
  106    -1             elm.css({
  107    -1               position: "fixed",
  108    -1               bottom: "",
  109    -1               top: offset
  110    -1             }).trigger("sticky_kit:unbottom");
   -1   106           if (enable_bottoming) {
   -1   107             will_bottom = scroll + height + offset > parent_height + parent_top;
   -1   108             if (bottomed && !will_bottom) {
   -1   109               bottomed = false;
   -1   110               elm.css({
   -1   111                 position: "fixed",
   -1   112                 bottom: "",
   -1   113                 top: offset
   -1   114               }).trigger("sticky_kit:unbottom");
   -1   115             }
  111   116           }
  112   117           if (scroll < top) {
  113   118             fixed = false;
@@ -158,7 +163,7 @@
  158   163             elm.trigger("sticky_kit:stick");
  159   164           }
  160   165         }
  161    -1         if (fixed) {
   -1   166         if (fixed && enable_bottoming) {
  162   167           if (will_bottom == null) {
  163   168             will_bottom = scroll + height + offset > parent_height + parent_top;
  164   169           }

diff --git a/jquery.sticky-kit.min.js b/jquery.sticky-kit.min.js

@@ -1,8 +1,8 @@
    1     1 /*
    2     2  Sticky-kit v1.0.5 | WTFPL | Leaf Corcoran 2014 | http://leafo.net
    3     3 */
    4    -1 (function(){var k,d;k=this.jQuery||window.jQuery;d=k(window);k.fn.stick_in_parent=function(e){var w,n,r,h,s,C,p,D;null==e&&(e={});s=e.sticky_class;w=e.inner_scrolling;h=e.parent;r=e.offset_top;n=e.spacer;null==r&&(r=0);null==h&&(h=void 0);null==w&&(w=!0);null==s&&(s="is_stuck");C=function(a,e,p,x,z,t,q){var u,A,m,y,c,f,B,v,g,b;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);f=a.parent();null!=h&&(f=f.closest(h));if(!f.length)throw"failed to find stick parent";u=m=!1;(g=null!=n?n&&a.closest(n):k("<div />"))&&
    5    -1 g.css("position",a.css("position"));B=function(){var c,d,l;c=parseInt(f.css("border-top-width"),10);d=parseInt(f.css("padding-top"),10);e=parseInt(f.css("padding-bottom"),10);p=f.offset().top+c+d;x=f.height();m&&(u=m=!1,null==n&&(a.insertAfter(g),g.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(s),l=!0);z=a.offset().top-parseInt(a.css("margin-top"),10)-r;t=a.outerHeight(!0);q=a.css("float");g&&g.css({width:a.outerWidth(!0),height:t,display:a.css("display"),"vertical-align":a.css("vertical-align"),
    6    -1 "float":q});if(l)return b()};B();if(t!==x)return y=void 0,c=r,b=function(){var b,k,l,h;l=d.scrollTop();null!=y&&(k=l-y);y=l;m?(h=l+t+c>x+p,u&&!h&&(u=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom")),l<z&&(m=!1,c=r,null==n&&("left"!==q&&"right"!==q||a.insertAfter(g),g.detach()),b={position:"",width:"",top:""},a.css(b).removeClass(s).trigger("sticky_kit:unstick")),w&&(b=d.height(),t>b&&!u&&(c-=k,c=Math.max(b-t,c),c=Math.min(r,c),m&&a.css({top:c+"px"})))):l>z&&(m=!0,b={position:"fixed",
    7    -1 top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(s),null==n&&(a.after(g),"left"!==q&&"right"!==q||g.append(a)),a.trigger("sticky_kit:stick"));if(m&&(null==h&&(h=l+t+c>x+p),!u&&h))return u=!0,"static"===f.css("position")&&f.css({position:"relative"}),a.css({position:"absolute",bottom:e,top:"auto"}).trigger("sticky_kit:bottom")},v=function(){B();return b()},A=function(){d.off("touchmove",b);d.off("scroll",b);d.off("resize",v);k(document.body).off("sticky_kit:recalc",
    8    -1 v);a.off("sticky_kit:detach",A);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:""});f.position("position","");if(m)return null==n&&("left"!==q&&"right"!==q||a.insertAfter(g),g.remove()),a.removeClass(s)},d.on("touchmove",b),d.on("scroll",b),d.on("resize",v),k(document.body).on("sticky_kit:recalc",v),a.on("sticky_kit:detach",A),setTimeout(b,0)}};p=0;for(D=this.length;p<D;p++)e=this[p],C(k(e));return this}}).call(this);
   -1     4 (function(){var k,e;k=this.jQuery||window.jQuery;e=k(window);k.fn.stick_in_parent=function(d){var v,x,n,r,h,s,D,p,E;null==d&&(d={});s=d.sticky_class;x=d.inner_scrolling;h=d.parent;r=d.offset_top;n=d.spacer;v=d.bottoming;null==r&&(r=0);null==h&&(h=void 0);null==x&&(x=!0);null==s&&(s="is_stuck");null==v&&(v=!0);D=function(a,d,p,y,A,t,q){var u,B,m,z,c,f,C,w,g,b;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);f=a.parent();null!=h&&(f=f.closest(h));if(!f.length)throw"failed to find stick parent";u=m=
   -1     5 !1;(g=null!=n?n&&a.closest(n):k("<div />"))&&g.css("position",a.css("position"));C=function(){var c,e,l;c=parseInt(f.css("border-top-width"),10);e=parseInt(f.css("padding-top"),10);d=parseInt(f.css("padding-bottom"),10);p=f.offset().top+c+e;y=f.height();m&&(u=m=!1,null==n&&(a.insertAfter(g),g.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(s),l=!0);A=a.offset().top-parseInt(a.css("margin-top"),10)-r;t=a.outerHeight(!0);q=a.css("float");g&&g.css({width:a.outerWidth(!0),height:t,
   -1     6 display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":q});if(l)return b()};C();if(t!==y)return z=void 0,c=r,b=function(){var b,k,l,h;l=e.scrollTop();null!=z&&(k=l-z);z=l;m?(v&&(h=l+t+c>y+p,u&&!h&&(u=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),l<A&&(m=!1,c=r,null==n&&("left"!==q&&"right"!==q||a.insertAfter(g),g.detach()),b={position:"",width:"",top:""},a.css(b).removeClass(s).trigger("sticky_kit:unstick")),x&&(b=e.height(),t>b&&!u&&(c-=k,c=Math.max(b-
   -1     7 t,c),c=Math.min(r,c),m&&a.css({top:c+"px"})))):l>A&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(s),null==n&&(a.after(g),"left"!==q&&"right"!==q||g.append(a)),a.trigger("sticky_kit:stick"));if(m&&v&&(null==h&&(h=l+t+c>y+p),!u&&h))return u=!0,"static"===f.css("position")&&f.css({position:"relative"}),a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")},w=function(){C();return b()},B=function(){e.off("touchmove",
   -1     8 b);e.off("scroll",b);e.off("resize",w);k(document.body).off("sticky_kit:recalc",w);a.off("sticky_kit:detach",B);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:""});f.position("position","");if(m)return null==n&&("left"!==q&&"right"!==q||a.insertAfter(g),g.remove()),a.removeClass(s)},e.on("touchmove",b),e.on("scroll",b),e.on("resize",w),k(document.body).on("sticky_kit:recalc",w),a.on("sticky_kit:detach",B),setTimeout(b,0)}};p=0;for(E=this.length;p<E;p++)d=this[p],D(k(d));return this}}).call(this);