1/* ======================================================================== 2 * Bootstrap: affix.js v3.3.5 3 * http://getbootstrap.com/javascript/#affix 4 * ======================================================================== 5 * Copyright 2011-2015 Twitter, Inc. 6 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 * ======================================================================== */ 8 9/** 10 * Customized by Ivan.Nginx 11 * 12 * - Refactored with eslint-config-theme-next style. 13 */ 14 15(function($) { 16 'use strict'; 17 18 // AFFIX CLASS DEFINITION 19 // ====================== 20 21 var Affix = function(element, options) { 22 this.options = $.extend({}, Affix.DEFAULTS, options); 23 24 this.$target = $(this.options.target) 25 .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) 26 .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)); 27 28 this.$element = $(element); 29 this.affixed = null; 30 this.unpin = null; 31 this.pinnedOffset = null; 32 33 this.checkPosition(); 34 }; 35 36 Affix.VERSION = '3.3.5'; 37 38 Affix.RESET = 'affix affix-top affix-bottom'; 39 40 Affix.DEFAULTS = { 41 offset: 0, 42 target: window 43 }; 44 45 Affix.prototype.getState = function(scrollHeight, height, offsetTop, offsetBottom) { 46 var scrollTop = this.$target.scrollTop(); 47 var position = this.$element.offset(); 48 var targetHeight = this.$target.height(); 49 50 if (offsetTop != null && this.affixed === 'top') return scrollTop < offsetTop ? 'top' : false; 51 52 if (this.affixed === 'bottom') { 53 if (offsetTop != null) return scrollTop + this.unpin <= position.top ? false : 'bottom'; 54 return scrollTop + targetHeight <= scrollHeight - offsetBottom ? false : 'bottom'; 55 } 56 57 var initializing = this.affixed == null; 58 var colliderTop = initializing ? scrollTop : position.top; 59 var colliderHeight = initializing ? targetHeight : height; 60 61 if (offsetTop != null && scrollTop <= offsetTop) return 'top'; 62 if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'; 63 64 return false; 65 }; 66 67 Affix.prototype.getPinnedOffset = function() { 68 if (this.pinnedOffset) return this.pinnedOffset; 69 this.$element.removeClass(Affix.RESET).addClass('affix'); 70 var scrollTop = this.$target.scrollTop(); 71 var position = this.$element.offset(); 72 return (this.pinnedOffset = position.top - scrollTop); 73 }; 74 75 Affix.prototype.checkPositionWithEventLoop = function() { 76 setTimeout($.proxy(this.checkPosition, this), 1); 77 }; 78 79 Affix.prototype.checkPosition = function() { 80 if (!this.$element.is(':visible')) return; 81 82 var height = this.$element.height(); 83 var offset = this.options.offset; 84 var offsetTop = offset.top; 85 var offsetBottom = offset.bottom; 86 var scrollHeight = Math.max($(document).height(), $(document.body).height()); 87 88 /* eslint-disable */ 89 if (typeof offset !== 'object') offsetBottom = offsetTop = offset; 90 if (typeof offsetTop === 'function') offsetTop = offset.top(this.$element); 91 if (typeof offsetBottom === 'function') offsetBottom = offset.bottom(this.$element); 92 /* eslint-enable */ 93 94 var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom); 95 96 if (this.affixed !== affix) { 97 if (this.unpin != null) this.$element.css('top', ''); 98 99 var affixType = 'affix' + (affix ? '-' + affix : ''); 100 var e = new $.Event(affixType + '.bs.affix'); 101 102 this.$element.trigger(e); 103 104 if (e.isDefaultPrevented()) return; 105 106 this.affixed = affix; 107 this.unpin = affix === 'bottom' ? this.getPinnedOffset() : null; 108 109 this.$element 110 .removeClass(Affix.RESET) 111 .addClass(affixType) 112 .trigger(affixType.replace('affix', 'affixed') + '.bs.affix'); 113 } 114 115 if (affix === 'bottom') { 116 this.$element.offset({ 117 top: scrollHeight - height - offsetBottom 118 }); 119 } 120 }; 121 122 // AFFIX PLUGIN DEFINITION 123 // ======================= 124 125 function Plugin(option) { 126 return this.each(function() { 127 var $this = $(this); 128 var data = $this.data('bs.affix'); 129 var options = typeof option === 'object' && option; 130 131 if (!data) $this.data('bs.affix', data = new Affix(this, options)); 132 if (typeof option === 'string') data[option](); 133 }); 134 } 135 136 var old = $.fn.affix; 137 138 $.fn.affix = Plugin; 139 $.fn.affix.Constructor = Affix; 140 141 // AFFIX NO CONFLICT 142 // ================= 143 144 $.fn.affix.noConflict = function() { 145 $.fn.affix = old; 146 return this; 147 }; 148 149 // AFFIX DATA-API 150 // ============== 151 152 $(window).on('load', function() { 153 $('[data-spy="affix"]').each(function() { 154 var $spy = $(this); 155 var data = $spy.data(); 156 157 data.offset = data.offset || {}; 158 159 /* eslint-disable */ 160 if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom; 161 if (data.offsetTop != null) data.offset.top = data.offsetTop; 162 /* eslint-enable */ 163 164 Plugin.call($spy, data); 165 }); 166 }); 167 168}(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.