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