vendor: 9,276 bytes, lines 1-268
1// Sticky Plugin v1.0.3 for jQuery 2// ============= 3// Author: Anthony Garand 4// Improvements by German M. Bravo (Kronuz) and Ruud Kamphuis (ruudk) 5// Improvements by Leonardo C. Daronco (daronco) 6// Created: 02/14/2011 7// Date: 07/20/2015 8// Website: http://stickyjs.com/ 9// Description: Makes an element on the page stick on the screen as you scroll 10// It will only set the 'top' and 'position' of your element, you 11// might need to adjust the width in some cases. 12 13(function (factory) { 14 if (typeof define === 'function' && define.amd) { 15 // AMD. Register as an anonymous module. 16 define(['jquery'], factory); 17 } else if (typeof module === 'object' && module.exports) { 18 // Node/CommonJS 19 module.exports = factory(require('jquery')); 20 } else { 21 // Browser globals 22 factory(jQuery); 23 } 24}(function ($) { 25 var slice = Array.prototype.slice; // save ref to original slice() 26 var splice = Array.prototype.splice; // save ref to original slice() 27 28 var defaults = { 29 topSpacing: 0, 30 bottomSpacing: 0, 31 className: 'is-sticky', 32 wrapperClassName: 'sticky-wrapper', 33 center: false, 34 getWidthFrom: '', 35 widthFromWrapper: true, // works only when .getWidthFrom is empty 36 responsiveWidth: false 37 }, 38 $window = $(window), 39 $document = $(document), 40 sticked = [], 41 windowHeight = $window.height(), 42 scroller = function() { 43 var scrollTop = $window.scrollTop(), 44 documentHeight = $document.height(), 45 dwh = documentHeight - windowHeight, 46 extra = (scrollTop > dwh) ? dwh - scrollTop : 0; 47 48 for (var i = 0, l = sticked.length; i < l; i++) { 49 var s = sticked[i], 50 elementTop = s.stickyWrapper.offset().top, 51 etse = elementTop - s.topSpacing - extra; 52 53 //update height in case of dynamic content 54 s.stickyWrapper.css('height', s.stickyElement.outerHeight()); 55 56 if (scrollTop <= etse) { 57 if (s.currentTop !== null) { 58 s.stickyElement 59 .css({ 60 'width': '', 61 'position': '', 62 'top': '' 63 }); 64 s.stickyElement.parent().removeClass(s.className); 65 s.stickyElement.trigger('sticky-end', [s]); 66 s.currentTop = null; 67 } 68 } 69 else { 70 var newTop = documentHeight - s.stickyElement.outerHeight() 71 - s.topSpacing - s.bottomSpacing - scrollTop - extra; 72 if (newTop < 0) { 73 newTop = newTop + s.topSpacing; 74 } else { 75 newTop = s.topSpacing; 76 } 77 if (s.currentTop !== newTop) { 78 var newWidth; 79 if (s.getWidthFrom) { 80 newWidth = $(s.getWidthFrom).width() || null; 81 } else if (s.widthFromWrapper) { 82 newWidth = s.stickyWrapper.width(); 83 } 84 if (newWidth == null) { 85 newWidth = s.stickyElement.width(); 86 } 87 s.stickyElement 88 .css('width', newWidth) 89 .css('position', 'fixed') 90 .css('top', newTop); 91 92 s.stickyElement.parent().addClass(s.className); 93 94 if (s.currentTop === null) { 95 s.stickyElement.trigger('sticky-start', [s]); 96 } else { 97 // sticky is started but it have to be repositioned 98 s.stickyElement.trigger('sticky-update', [s]); 99 } 100 101 if (s.currentTop === s.topSpacing && s.currentTop > newTop || s.currentTop === null && newTop < s.topSpacing) { 102 // just reached bottom || just started to stick but bottom is already reached 103 s.stickyElement.trigger('sticky-bottom-reached', [s]); 104 } else if(s.currentTop !== null && newTop === s.topSpacing && s.currentTop < newTop) { 105 // sticky is started && sticked at topSpacing && overflowing from top just finished 106 s.stickyElement.trigger('sticky-bottom-unreached', [s]); 107 } 108 109 s.currentTop = newTop; 110 } 111 112 // Check if sticky has reached end of container and stop sticking 113 var stickyWrapperContainer = s.stickyWrapper.parent(); 114 var unstick = (s.stickyElement.offset().top + s.stickyElement.outerHeight() >= stickyWrapperContainer.offset().top + stickyWrapperContainer.outerHeight()) && (s.stickyElement.offset().top <= s.topSpacing); 115 116 if( unstick ) { 117 s.stickyElement 118 .css('position', 'absolute') 119 .css('top', '') 120 .css('bottom', 0); 121 } else { 122 s.stickyElement 123 .css('position', 'fixed') 124 .css('top', newTop) 125 .css('bottom', ''); 126 } 127 } 128 } 129 }, 130 resizer = function() { 131 windowHeight = $window.height(); 132 133 for (var i = 0, l = sticked.length; i < l; i++) { 134 var s = sticked[i]; 135 var newWidth = null; 136 if (s.getWidthFrom) { 137 if (s.responsiveWidth) { 138 newWidth = $(s.getWidthFrom).width(); 139 } 140 } else if(s.widthFromWrapper) { 141 newWidth = s.stickyWrapper.width(); 142 } 143 if (newWidth != null) { 144 s.stickyElement.css('width', newWidth); 145 } 146 } 147 }, 148 methods = { 149 init: function(options) { 150 var o = $.extend({}, defaults, options); 151 return this.each(function() { 152 var stickyElement = $(this); 153 154 var stickyId = stickyElement.attr('id'); 155 var wrapperId = stickyId ? stickyId + '-' + defaults.wrapperClassName : defaults.wrapperClassName; 156 var wrapper = $('<div></div>') 157 .attr('id', wrapperId) 158 .addClass(o.wrapperClassName); 159 160 stickyElement.wrapAll(wrapper); 161 162 var stickyWrapper = stickyElement.parent(); 163 164 if (o.center) { 165 stickyWrapper.css({width:stickyElement.outerWidth(),marginLeft:"auto",marginRight:"auto"}); 166 } 167 168 if (stickyElement.css("float") === "right") { 169 stickyElement.css({"float":"none"}).parent().css({"float":"right"}); 170 } 171 172 o.stickyElement = stickyElement; 173 o.stickyWrapper = stickyWrapper; 174 o.currentTop = null; 175 176 sticked.push(o); 177 178 methods.setWrapperHeight(this); 179 methods.setupChangeListeners(this); 180 }); 181 }, 182 183 setWrapperHeight: function(stickyElement) { 184 var element = $(stickyElement); 185 var stickyWrapper = element.parent(); 186 if (stickyWrapper) { 187 stickyWrapper.css('height', element.outerHeight()); 188 } 189 }, 190 191 setupChangeListeners: function(stickyElement) { 192 if (window.MutationObserver) { 193 var mutationObserver = new window.MutationObserver(function(mutations) { 194 if (mutations[0].addedNodes.length || mutations[0].removedNodes.length) { 195 methods.setWrapperHeight(stickyElement); 196 } 197 }); 198 mutationObserver.observe(stickyElement, {subtree: true, childList: true}); 199 } else { 200 stickyElement.addEventListener('DOMNodeInserted', function() { 201 methods.setWrapperHeight(stickyElement); 202 }, false); 203 stickyElement.addEventListener('DOMNodeRemoved', function() { 204 methods.setWrapperHeight(stickyElement); 205 }, false); 206 } 207 }, 208 update: scroller, 209 unstick: function(options) { 210 return this.each(function() { 211 var that = this; 212 var unstickyElement = $(that); 213 214 var removeIdx = -1; 215 var i = sticked.length; 216 while (i-- > 0) { 217 if (sticked[i].stickyElement.get(0) === that) { 218 splice.call(sticked,i,1); 219 removeIdx = i; 220 } 221 } 222 if(removeIdx !== -1) { 223 unstickyElement.unwrap(); 224 unstickyElement 225 .css({ 226 'width': '', 227 'position': '', 228 'top': '', 229 'float': '' 230 }) 231 ; 232 } 233 }); 234 } 235 }; 236 237 // should be more efficient than using $window.scroll(scroller) and $window.resize(resizer): 238 if (window.addEventListener) { 239 window.addEventListener('scroll', scroller, false); 240 window.addEventListener('resize', resizer, false); 241 } else if (window.attachEvent) { 242 window.attachEvent('onscroll', scroller); 243 window.attachEvent('onresize', resizer); 244 } 245 246 $.fn.sticky = function(method) { 247 if (methods[method]) { 248 return methods[method].apply(this, slice.call(arguments, 1)); 249 } else if (typeof method === 'object' || !method ) { 250 return methods.init.apply( this, arguments ); 251 } else { 252 $.error('Method ' + method + ' does not exist on jQuery.sticky'); 253 } 254 }; 255 256 $.fn.unstick = function(method) { 257 if (methods[method]) { 258 return methods[method].apply(this, slice.call(arguments, 1)); 259 } else if (typeof method === 'object' || !method ) { 260 return methods.unstick.apply( this, arguments ); 261 } else { 262 $.error('Method ' + method + ' does not exist on jQuery.sticky'); 263 } 264 }; 265 $(function() { 266 setTimeout(scroller, 0); 267 }); 268}));
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.