// sticky plugin // ============= // author: anthony garand // improvements by german m. bravo (kronuz) and ruud kamphuis (ruudk) // improvements by leonardo c. daronco (daronco) // created: 2/14/2011 // date: 2/12/2012 // website: http://labs.anthonygarand.com/sticky // description: makes an element on the page stick on the screen as you scroll // it will only set the 'top' and 'position' of your element, you // might need to adjust the width in some cases. (function($) { var defaults = { topspacing: 0, bottomspacing: 0, classname: 'is-sticky', wrapperclassname: 'sticky-wrapper' }, $window = $(window), $document = $(document), sticked = [], windowheight = $window.height(), scroller = function() { var scrolltop = $window.scrolltop(), documentheight = $document.height(), dwh = documentheight - windowheight, extra = (scrolltop > dwh) ? dwh - scrolltop : 0; for (var i = 0; i < sticked.length; i++) { var s = sticked[i], elementtop = s.stickywrapper.offset().top, etse = elementtop - s.topspacing - extra; if (scrolltop <= etse) { if (s.currenttop !== null) { s.stickyelement .css('position', '') .css('top', '') .removeclass(s.classname); s.stickyelement.parent().removeclass(s.classname); s.currenttop = null; } } else { var newtop = documentheight - s.stickyelement.outerheight() - s.topspacing - s.bottomspacing - scrolltop - extra; if (newtop < 0) { newtop = newtop + s.topspacing; } else { newtop = s.topspacing; } if (s.currenttop != newtop) { s.stickyelement .css('position', 'fixed') .css('top', newtop) .addclass(s.classname); s.stickyelement.parent().addclass(s.classname); s.currenttop = newtop; } } } }, resizer = function() { windowheight = $window.height(); }, methods = { init: function(options) { var o = $.extend(defaults, options); return this.each(function() { var stickyelement = $(this); stickyid = stickyelement.attr('id'); wrapper = $('
') .attr('id', stickyid + '-sticky-wrapper') .addclass(o.wrapperclassname); stickyelement.wrapall(wrapper); var stickywrapper = stickyelement.parent(); stickywrapper.css('height', stickyelement.outerheight()); sticked.push({ topspacing: o.topspacing, bottomspacing: o.bottomspacing, stickyelement: stickyelement, currenttop: null, stickywrapper: stickywrapper, classname: o.classname }); }); }, update: scroller }; // should be more efficient than using $window.scroll(scroller) and $window.resize(resizer): if (window.addeventlistener) { window.addeventlistener('scroll', scroller, false); window.addeventlistener('resize', resizer, false); } else if (window.attachevent) { window.attachevent('onscroll', scroller); window.attachevent('onresize', resizer); } $.fn.sticky = function(method) { if (methods[method]) { return methods[method].apply(this, array.prototype.slice.call(arguments, 1)); } else if (typeof method === 'object' || !method ) { return methods.init.apply( this, arguments ); } else { $.error('method ' + method + ' does not exist on jquery.sticky'); } }; $(function() { settimeout(scroller, 0); }); })(jquery);