vendor: 5,347 bytes, lines 1-150
1/* 2 * ScrollToFixed 3 * https://github.com/bigspotteddog/ScrollToFixed 4 * 5 * Copyright (c) 2011 Joseph Cava-Lynch 6 * MIT license 7 */ 8(function($) { 9 $.isScrollToFixed = function(el) { 10 return !!$(el).data('ScrollToFixed'); 11 }; 12 13 $.ScrollToFixed = function(el, options) { 14 // To avoid scope issues, use 'base' instead of 'this' to reference this 15 // class from internal events and functions. 16 var base = this; 17 18 // Access to jQuery and DOM versions of element. 19 base.$el = $(el); 20 base.el = el; 21 22 // Add a reverse reference to the DOM object. 23 base.$el.data('ScrollToFixed', base); 24 25 // A flag so we know if the scroll has been reset. 26 var isReset = false; 27 28 // The element that was given to us to fix if scrolled above the top of 29 // the page. 30 var target = base.$el; 31 32 var position; 33 var originalPosition; 34 var originalOffsetTop; 35 var originalZIndex; 36 37 // The offset top of the element when resetScroll was called. This is 38 // used to determine if we have scrolled past the top of the element. 39 var offsetTop = 0; 40 41 // The offset left of the element when resetScroll was called. This is 42 // used to move the element left or right relative to the horizontal 43 // scroll. 44 var offsetLeft = 0; 45 var originalOffsetLeft = -1; 46 47 // This last offset used to move the element horizontally. This is used 48 // to determine if we need to move the element because we would not want 49 // to do that for no reason. 50 var lastOffsetLeft = -1; 51 52 // This is the element used to fill the void left by the target element 53 // when it goes fixed; otherwise, everything below it moves up the page. 54 var spacer = null; 55 56 var spacerClass; 57 58 var className; 59 60 // Capture the original offsets for the target element. This needs to be 61 // called whenever the page size changes or when the page is first 62 // scrolled. For some reason, calling this before the page is first 63 // scrolled causes the element to become fixed too late. 64 function resetScroll() { 65 // Set the element to it original positioning. 66 target.trigger('preUnfixed.ScrollToFixed'); 67 setUnfixed(); 68 target.trigger('unfixed.ScrollToFixed'); 69 70 // Reset the last offset used to determine if the page has moved 71 // horizontally. 72 lastOffsetLeft = -1; 73 74 // Capture the offset top of the target element. 75 offsetTop = target.offset().top; 76 77 // Capture the offset left of the target element. 78 offsetLeft = target.offset().left; 79 80 // If the offsets option is on, alter the left offset. 81 if (base.options.offsets) { 82 offsetLeft += (target.offset().left - target.position().left); 83 } 84 85 if (originalOffsetLeft == -1) { 86 originalOffsetLeft = offsetLeft; 87 } 88 89 position = target.css('position'); 90 91 // Set that this has been called at least once. 92 isReset = true; 93 94 if (base.options.bottom != -1) { 95 target.trigger('preFixed.ScrollToFixed'); 96 setFixed(); 97 target.trigger('fixed.ScrollToFixed'); 98 } 99 } 100 101 function getLimit() { 102 var limit = base.options.limit; 103 if (!limit) return 0; 104 105 if (typeof(limit) === 'function') { 106 return limit.apply(target); 107 } 108 return limit; 109 } 110 111 // Returns whether the target element is fixed or not. 112 function isFixed() { 113 return position === 'fixed'; 114 } 115 116 // Returns whether the target element is absolute or not. 117 function isAbsolute() { 118 return position === 'absolute'; 119 } 120 121 function isUnfixed() { 122 return !(isFixed() || isAbsolute()); 123 } 124 125 // Sets the target element to fixed. Also, sets the spacer to fill the 126 // void left by the target element. 127 function setFixed() { 128 // Only fix the target element and the spacer if we need to. 129 if (!isFixed()) { 130 // Set the spacer to fill the height and width of the target 131 // element, then display it. 132 spacer.css({ 133 'display' : target.css('display'), 134 'width' : target.outerWidth(true), 135 'height' : target.outerHeight(true), 136 'float' : target.css('float') 137 }); 138 139 // Set the target element to fixed and set its width so it does 140 // not fill the rest of the page horizontally. Also, set its top 141 // to the margin top specified in the options. 142 143 cssOptions={ 144 'z-index' : base.options.zIndex, 145 'position' : 'fixed', 146 'top' : base.options.bottom == -1?getMarginTop():'', 147 'bottom' : base.options.bottom == -1?'':base.options.bottom, 148 'margin-left' : '0px' 149 } 150 if (!base.options.dontSetWidth){ cssOptions['width']=target.
150width(); }; 151 152 target.css(cssOptions); 153 154 target.addClass(base.options.baseClassName); 155 156 if (base.options.className) { 157 target.addClass(base.options.className); 158 } 159 160 position = 'fixed'; 161 } 162 } 163 164 function setAbsolute() { 165 166 var top = getLimit(); 167 var left = offsetLeft; 168 169 if (base.options.removeOffsets) { 170 left = ''; 171 top = top - offsetTop; 172 } 173 174 cssOptions={ 175 'position' : 'absolute', 176 'top' : top, 177 'left' : left, 178 'margin-left' : '0px', 179 'bottom' : '' 180 } 181 if (!base.options.dontSetWidth){ cssOptions['width']=target.width(
vendor: 11,271 bytes, lines 181-470
181); }; 182 183 target.css(cssOptions); 184 185 position = 'absolute'; 186 } 187 188 // Sets the target element back to unfixed. Also, hides the spacer. 189 function setUnfixed() { 190 // Only unfix the target element and the spacer if we need to. 191 if (!isUnfixed()) { 192 lastOffsetLeft = -1; 193 194 // Hide the spacer now that the target element will fill the 195 // space. 196 spacer.css('display', 'none'); 197 198 // Remove the style attributes that were added to the target. 199 // This will reverse the target back to the its original style. 200 target.css({ 201 'z-index' : originalZIndex, 202 'width' : '', 203 'position' : originalPosition, 204 'left' : '', 205 'top' : originalOffsetTop, 206 'margin-left' : '' 207 }); 208 209 target.removeClass('scroll-to-fixed-fixed'); 210 211 if (base.options.className) { 212 target.removeClass(base.options.className); 213 } 214 215 position = null; 216 } 217 } 218 219 // Moves the target element left or right relative to the horizontal 220 // scroll position. 221 function setLeft(x) { 222 // Only if the scroll is not what it was last time we did this. 223 if (x != lastOffsetLeft) { 224 // Move the target element horizontally relative to its original 225 // horizontal position. 226 target.css('left', offsetLeft - x); 227 228 // Hold the last horizontal position set. 229 lastOffsetLeft = x; 230 } 231 } 232 233 function getMarginTop() { 234 var marginTop = base.options.marginTop; 235 if (!marginTop) return 0; 236 237 if (typeof(marginTop) === 'function') { 238 return marginTop.apply(target); 239 } 240 return marginTop; 241 } 242 243 // Checks to see if we need to do something based on new scroll position 244 // of the page. 245 function checkScroll() { 246 if (!$.isScrollToFixed(target)) return; 247 var wasReset = isReset; 248 249 // If resetScroll has not yet been called, call it. This only 250 // happens once. 251 if (!isReset) { 252 resetScroll(); 253 } else if (isUnfixed()) { 254 // if the offset has changed since the last scroll, 255 // we need to get it again. 256 257 // Capture the offset top of the target element. 258 offsetTop = target.offset().top; 259 260 // Capture the offset left of the target element. 261 offsetLeft = target.offset().left; 262 } 263 264 // Grab the current horizontal scroll position. 265 var x = $(window).scrollLeft(); 266 267 // Grab the current vertical scroll position. 268 var y = $(window).scrollTop(); 269 270 // Get the limit, if there is one. 271 var limit = getLimit(); 272 273 // If the vertical scroll position, plus the optional margin, would 274 // put the target element at the specified limit, set the target 275 // element to absolute. 276 if (base.options.minWidth && $(window).width() < base.options.minWidth) { 277 if (!isUnfixed() || !wasReset) { 278 postPosition(); 279 target.trigger('preUnfixed.ScrollToFixed'); 280 setUnfixed(); 281 target.trigger('unfixed.ScrollToFixed'); 282 } 283 } else if (base.options.maxWidth && $(window).width() > base.options.maxWidth) { 284 if (!isUnfixed() || !wasReset) { 285 postPosition(); 286 target.trigger('preUnfixed.ScrollToFixed'); 287 setUnfixed(); 288 target.trigger('unfixed.ScrollToFixed'); 289 } 290 } else if (base.options.bottom == -1) { 291 // If the vertical scroll position, plus the optional margin, would 292 // put the target element at the specified limit, set the target 293 // element to absolute. 294 if (limit > 0 && y >= limit - getMarginTop()) { 295 if (!isAbsolute() || !wasReset) { 296 postPosition(); 297 target.trigger('preAbsolute.ScrollToFixed'); 298 setAbsolute(); 299 target.trigger('unfixed.ScrollToFixed'); 300 } 301 // If the vertical scroll position, plus the optional margin, would 302 // put the target element above the top of the page, set the target 303 // element to fixed. 304 } else if (y >= offsetTop - getMarginTop()) { 305 if (!isFixed() || !wasReset) { 306 postPosition(); 307 target.trigger('preFixed.ScrollToFixed'); 308 309 // Set the target element to fixed. 310 setFixed(); 311 312 // Reset the last offset left because we just went fixed. 313 lastOffsetLeft = -1; 314 315 target.trigger('fixed.ScrollToFixed'); 316 } 317 // If the page has been scrolled horizontally as well, move the 318 // target element accordingly. 319 setLeft(x); 320 } else { 321 // Set the target element to unfixed, placing it where it was 322 // before. 323 if (!isUnfixed() || !wasReset) { 324 postPosition(); 325 target.trigger('preUnfixed.ScrollToFixed'); 326 setUnfixed(); 327 target.trigger('unfixed.ScrollToFixed'); 328 } 329 } 330 } else { 331 if (limit > 0) { 332 if (y + $(window).height() - target.outerHeight(true) >= limit - (getMarginTop() || -getBottom())) { 333 if (isFixed()) { 334 postPosition(); 335 target.trigger('preUnfixed.ScrollToFixed'); 336 337 if (originalPosition === 'absolute') { 338 setAbsolute(); 339 } else { 340 setUnfixed(); 341 } 342 343 target.trigger('unfixed.ScrollToFixed'); 344 } 345 } else { 346 if (!isFixed()) { 347 postPosition(); 348 target.trigger('preFixed.ScrollToFixed'); 349 setFixed(); 350 } 351 setLeft(x); 352 target.trigger('fixed.ScrollToFixed'); 353 } 354 } else { 355 setLeft(x); 356 } 357 } 358 } 359 360 function getBottom() { 361 if (!base.options.bottom) return 0; 362 return base.options.bottom; 363 } 364 365 function postPosition() { 366 var position = target.css('position'); 367 368 if (position == 'absolute') { 369 target.trigger('postAbsolute.ScrollToFixed'); 370 } else if (position == 'fixed') { 371 target.trigger('postFixed.ScrollToFixed'); 372 } else { 373 target.trigger('postUnfixed.ScrollToFixed'); 374 } 375 } 376 377 var windowResize = function(event) { 378 // Check if the element is visible before updating it's position, which 379 // improves behavior with responsive designs where this element is hidden. 380 if(target.is(':visible')) { 381 isReset = false; 382 checkScroll(); 383 } 384 } 385 386 var windowScroll = function(event) { 387 (!!window.requestAnimationFrame) ? requestAnimationFrame(checkScroll) : checkScroll(); 388 } 389 390 // From: http://kangax.github.com/cft/#IS_POSITION_FIXED_SUPPORTED 391 var isPositionFixedSupported = function() { 392 var container = document.body; 393 394 if (document.createElement && container && container.appendChild && container.removeChild) { 395 var el = document.createElement('div'); 396 397 if (!el.getBoundingClientRect) return null; 398 399 el.innerHTML = 'x'; 400 el.style.cssText = 'position:fixed;top:100px;'; 401 container.appendChild(el); 402 403 var originalHeight = container.style.height, 404 originalScrollTop = container.scrollTop; 405 406 container.style.height = '3000px'; 407 container.scrollTop = 500; 408 409 var elementTop = el.getBoundingClientRect().top; 410 container.style.height = originalHeight; 411 412 var isSupported = (elementTop === 100); 413 container.removeChild(el); 414 container.scrollTop = originalScrollTop; 415 416 return isSupported; 417 } 418 419 return null; 420 } 421 422 var preventDefault = function(e) { 423 e = e || window.event; 424 if (e.preventDefault) { 425 e.preventDefault(); 426 } 427 e.returnValue = false; 428 } 429 430 // Initializes this plugin. Captures the options passed in, turns this 431 // off for devices that do not support fixed position, adds the spacer, 432 // and binds to the window scroll and resize events. 433 base.init = function() { 434 // Capture the options for this plugin. 435 base.options = $.extend({}, $.ScrollToFixed.defaultOptions, options); 436 437 originalZIndex = target.css('z-index') 438 439 // Turn off this functionality for devices that do not support it. 440 // if (!(base.options && base.options.dontCheckForPositionFixedSupport)) { 441 // var fixedSupported = isPositionFixedSupported(); 442 // if (!fixedSupported) return; 443 // } 444 445 // Put the target element on top of everything that could be below 446 // it. This reduces flicker when the target element is transitioning 447 // to fixed. 448 base.$el.css('z-index', base.options.zIndex); 449 450 // Create a spacer element to fill the void left by the target 451 // element when it goes fixed. 452 spacer = $('<div />'); 453 454 position = target.css('position'); 455 originalPosition = target.css('position'); 456 457 originalOffsetTop = target.css('top'); 458 459 // Place the spacer right after the target element. 460 if (isUnfixed()) base.$el.after(spacer); 461 462 // Reset the target element offsets when the window is resized, then 463 // check to see if we need to fix or unfix the target element. 464 $(window).bind('resize.ScrollToFixed', windowResize); 465 466 // When the window scrolls, check to see if we need to fix or unfix 467 // the target element. 468 $(window).bind('scroll.ScrollToFixed', windowScroll); 469 470
vendor: 2,786 bytes, lines 470-552
470if (base.options.preFixed) { 471 target.bind('preFixed.ScrollToFixed', base.options.preFixed); 472 } 473 if (base.options.postFixed) { 474 target.bind('postFixed.ScrollToFixed', base.options.postFixed); 475 } 476 if (base.options.preUnfixed) { 477 target.bind('preUnfixed.ScrollToFixed', base.options.preUnfixed); 478 } 479 if (base.options.postUnfixed) { 480 target.bind('postUnfixed.ScrollToFixed', base.options.postUnfixed); 481 } 482 if (base.options.preAbsolute) { 483 target.bind('preAbsolute.ScrollToFixed', base.options.preAbsolute); 484 } 485 if (base.options.postAbsolute) { 486 target.bind('postAbsolute.ScrollToFixed', base.options.postAbsolute); 487 } 488 if (base.options.fixed) { 489 target.bind('fixed.ScrollToFixed', base.options.fixed); 490 } 491 if (base.options.unfixed) { 492 target.bind('unfixed.ScrollToFixed', base.options.unfixed); 493 } 494 495 if (base.options.spacerClass) { 496 spacer.addClass(base.options.spacerClass); 497 } 498 499 target.bind('resize.ScrollToFixed', function() { 500 spacer.height(target.height()); 501 }); 502 503 target.bind('scroll.ScrollToFixed', function() { 504 target.trigger('preUnfixed.ScrollToFixed'); 505 setUnfixed(); 506 target.trigger('unfixed.ScrollToFixed'); 507 checkScroll(); 508 }); 509 510 target.bind('detach.ScrollToFixed', function(ev) { 511 preventDefault(ev); 512 513 target.trigger('preUnfixed.ScrollToFixed'); 514 setUnfixed(); 515 target.trigger('unfixed.ScrollToFixed'); 516 517 $(window).unbind('resize.ScrollToFixed', windowResize); 518 $(window).unbind('scroll.ScrollToFixed', windowScroll); 519 520 target.unbind('.ScrollToFixed'); 521 522 //remove spacer from dom 523 spacer.remove(); 524 525 base.$el.removeData('ScrollToFixed'); 526 }); 527 528 // Reset everything. 529 windowResize(); 530 }; 531 532 // Initialize the plugin. 533 base.init(); 534 }; 535 536 // Sets the option defaults. 537 $.ScrollToFixed.defaultOptions = { 538 marginTop : 0, 539 limit : 0, 540 bottom : -1, 541 zIndex : 1000, 542 baseClassName: 'scroll-to-fixed-fixed' 543 }; 544 545 // Returns enhanced elements that will fix to the top of the page when the 546 // page is scrolled. 547 $.fn.scrollToFixed = function(options) { 548 return this.each(function() { 549 (new $.ScrollToFixed(this, options)); 550 }); 551 }; 552})(jQuery);
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.