1/*! UIkit 2.26.4 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */ 2(function(addon) { 3 4 var component; 5 6 if (window.UIkit) { 7 component = addon(UIkit); 8 } 9 10 if (typeof define == "function" && define.amd) { 11 define("uikit-sticky", ["uikit"], function(){ 12 return component || addon(UIkit); 13 }); 14 } 15 16})(function(UI){ 17 18 "use strict"; 19 20 var $win = UI.$win, 21 $doc = UI.$doc, 22 sticked = [], 23 direction = 1; 24 25 UI.component('sticky', { 26 27 defaults: { 28 top : 0, 29 bottom : 0, 30 animation : '', 31 clsinit : 'uk-sticky-init', 32 clsactive : 'uk-active', 33 clsinactive : '', 34 getWidthFrom : '', 35 showup : false, 36 boundary : false, 37 media : false, 38 target : false, 39 disabled : false 40 }, 41 42 boot: function() { 43 44 // should be more efficient than using $win.scroll(checkscrollposition): 45 UI.$doc.on('scrolling.uk.document', function(e, data) { 46 if (!data || !data.dir) return; 47 direction = data.dir.y; 48 checkscrollposition(); 49 }); 50 51 UI.$win.on('resize orientationchange', UI.Utils.debounce(function() { 52 53 if (!sticked.length) return; 54 55 for (var i = 0; i < sticked.length; i++) { 56 sticked[i].reset(true); 57 sticked[i].self.computeWrapper(); 58 } 59 60 checkscrollposition(); 61 }, 100)); 62 63 // init code 64 UI.ready(function(context) { 65 66 setTimeout(function(){ 67 68 UI.$("[data-uk-sticky]", context).each(function(){ 69 70 var $ele = UI.$(this); 71 72 if (!$ele.data("sticky")) { 73 UI.sticky($ele, UI.Utils.options($ele.attr('data-uk-sticky'))); 74 } 75 }); 76 77 checkscrollposition(); 78 }, 0); 79 }); 80 }, 81 82 init: function() { 83 84 var boundary = this.options.boundary, boundtoparent; 85 86 this.wrapper = this.element.wrap('<div class="uk-sticky-placeholder"></div>').parent(); 87 this.computeWrapper(); 88 this.wrapper.css({ 89 'margin-top' : this.element.css('margin-top'), 90 'margin-bottom' : this.element.css('margin-bottom'), 91 'margin-left' : this.element.css('margin-left'), 92 'margin-right' : this.element.css('margin-right') 93 }) 94 this.element.css('margin', 0); 95 96 if (boundary) { 97 98 if (boundary === true || boundary[0] === '!') { 99 100 boundary = boundary === true ? this.wrapper.parent() : this.wrapper.closest(boundary.substr(1)); 101 boundtoparent = true; 102 103 } else if (typeof boundary === "string") { 104 boundary = UI.$(boundary); 105 } 106 } 107 108 this.sticky = { 109 self : this, 110 options : this.options, 111 element : this.element, 112 currentTop : null, 113 wrapper : this.wrapper, 114 init : false, 115 getWidthFrom : UI.$(this.options.getWidthFrom || this.wrapper), 116 boundary : boundary, 117 boundtoparent : boundtoparent, 118 top : 0, 119 calcTop : function() { 120 121 var top = this.options.top; 122 123 // dynamic top parameter 124 if (this.options.top && typeof(this.options.top) == 'string') { 125 126 // e.g. 50vh 127 if (this.options.top.match(/^(-|)(\d+)vh$/)) { 128 top = window.innerHeight * parseInt(this.options.top, 10)/100; 129 // e.g. #elementId, or .class-1,class-2,.class-3 (first found is used) 130 } else { 131 132 var topElement = UI.$(this.options.top).first(); 133 134 if (topElement.length && topElement.is(':visible')) { 135 top = -1 * ((topElement.offset().top + topElement.outerHeight()) - this.wrapper.offset().top); 136 } 137 } 138 139 } 140 141 this.top = top; 142 }, 143 144 reset: function(force) { 145 146 this.calcTop(); 147 148 var finalize = function() { 149 this.element.css({"position":"", "top":"", "width":"", "left"
149:"", "margin":"0"}); 150 this.element.removeClass([this.options.animation, 'uk-animation-reverse', this.options.clsactive].join(' ')); 151 this.element.addClass(this.options.clsinactive); 152 this.element.trigger('inactive.uk.sticky'); 153 154 this.currentTop = null; 155 this.animate = false; 156 157 }.bind(this); 158 159 160 if (!force && this.options.animation && UI.support.animation && !UI.Utils.isInView(this.wrapper)) { 161 162 this.animate = true; 163 164 this.element.removeClass(this.options.animation).one(UI.support.animation.end, function(){ 165 finalize(); 166 }).width(); // force redraw 167 168 this.element.addClass(this.options.animation+' '+'uk-animation-reverse'); 169 } else { 170 finalize(); 171 } 172 }, 173 174 check: function() { 175 176 if (this.options.disabled) { 177 return false; 178 } 179 180 if (this.options.media) { 181 182 switch(typeof(this.options.media)) { 183 case 'number': 184 if (window.innerWidth < this.options.media) { 185 return false; 186 } 187 break; 188 case 'string': 189 if (window.matchMedia && !window.matchMedia(this.options.media).matches) { 190 return false; 191 } 192 break; 193 } 194 } 195 196 var scrollTop = $win.scrollTop(), 197 documentHeight = $doc.height(), 198 dwh = documentHeight - window.innerHeight, 199 extra = (scrollTop > dwh) ? dwh - scrollTop : 0, 200 elementTop = this.wrapper.offset().top, 201 etse = elementTop - this.top - extra, 202 active = (scrollTop >= etse); 203 204 if (active && this.options.showup) { 205 206 // set inactiv if scrolling down 207 if (direction == 1) { 208 active = false; 209 } 210 211 // set inactive when wrapper is still in view 212 if (direction == -1 && !this.element.hasClass(this.options.clsactive) && UI.Utils.isInView(this.wrapper)) { 213 active = false; 214 } 215 } 216 217 return active; 218 } 219 }; 220 221 this.sticky.calcTop(); 222 223 sticked.push(this.sticky); 224 }, 225 226 update: function() { 227 checkscrollposition(this.sticky); 228 }, 229 230 enable: function() { 231 this.options.disabled = false; 232 this.update(); 233 }, 234 235 disable: function(force) { 236 this.options.disabled = true; 237 this.sticky.reset(force); 238 }, 239 240 computeWrapper: function() { 241 242 this.wrapper.css({ 243 'height' : ['absolute','fixed'].indexOf(this.element.css('position')) == -1 ? this.element.outerHeight() : '', 244 'float' : this.element.css('float') != 'none' ? this.element.css('float') : '' 245 }); 246 247 if (this.element.css('position') == 'fixed') { 248 this.element.css({ 249 width: this.sticky.getWidthFrom.length ? this.sticky.getWidthFrom.width() : this.element.width() 250 }); 251 } 252 } 253 }); 254 255 function checkscrollposition(direction) { 256 257 var stickies = arguments.length ? arguments : sticked; 258 259 if (!stickies.length || $win.scrollTop() < 0) return; 260 261 var scrollTop = $win.scrollTop(), 262 documentHeight = $doc.height(), 263 windowHeight = $win.height(), 264 dwh = documentHeight - windowHeight, 265 extra = (scrollTop > dwh) ? dwh - scrollTop : 0, 266 newTop, containerBottom, stickyHeight, sticky; 267 268 for (var i = 0; i < stickies.length; i++) { 269 270 sticky = stickies[i]; 271 272 if (!sticky.element.is(":visible") || sticky.animate) { 273 continue; 274 } 275 276 if (!sticky.check()) { 277 278 if (sticky.currentTop !== null) { 279 sticky.reset(); 280 } 281 282 } else { 283 284 if (sticky.top < 0) { 285 newTop = 0; 286 } else { 287 stickyHeight = sticky.element.outerHeight(); 288 newTop = documentHeight - stickyHeight - sticky.top - sticky.options.bottom - scrollTop - extra; 289 newTop = newTop < 0 ? newTop + sticky.top : sticky.top; 290 } 291 292 if (sticky.boundary && sticky.boundary.length) { 293 294 var bTop = sticky.boundary.offset().top; 295 296 if (sticky.boundtoparent) { 297 containerBottom = documentHeight - (bTop + sticky.boundary.outerHeight()) + parseInt(sticky.boundary.css('padding-bottom')); 298 } else { 299 containerBottom = documentHeight - bTop; 300 } 301 302 newTop = (scrollTop + stickyHeight) > (documentHeight - containerBottom - (sticky.top < 0 ? 0 : sticky.top)) ? (documentHeight - containerBottom) - (scrollTop + stickyHeight) : newTop; 303 } 304 305 306 if (sticky.currentTop != newTop) { 307 308 sticky.element.css({ 309 position : "fixed", 310 top : newTop, 311 width : sticky.getWidthFrom.length ? sticky.getWidthFrom.width() : sticky.element.width() 312 }); 313 314 if (!sticky.init) { 315 316 sticky.element.addClass(sticky.options.clsinit); 317 318 if (location.hash && scrollTop > 0 && sticky.options.target) { 319 320 var $target = UI.$(location.hash); 321 322 if ($target.length) { 323 324 setTimeout((function($target, sticky){ 325 326 return function() { 327 328 sticky.element.width(); // force redraw 329 330 var offset = $target.offset(), 331 maxoffset = offset.top + $target.outerHeight(), 332 stickyOffset = sticky.element.offset(), 333 stickyHeight = sticky.element.outerHeight(), 334 stickyMaxOffset = stickyOffset.top + stickyHeight; 335 336 if (stickyOffset.top < maxoffset && offset.top < stickyMaxOffset) { 337 scrollTop = offset.top - stickyHeight - sticky.options.target; 338 window.scrollTo(0, scrollTop); 339 } 340 }; 341 342 })($target, sticky), 0); 343 } 344 } 345 } 346 347 sticky.element.addClass(sticky.options.clsactive).removeClass(sticky.options.clsinactive); 348 sticky.element.trigger('active.uk.sticky'); 349 sticky.element.css('margin', ''); 350 351 if (sticky.options.animation && sticky.init && !UI.Utils.isInView(sticky.wrapper)) { 352 sticky.element.addClass(sticky.options.animation); 353 } 354 355 sticky.currentTop = newTop; 356 } 357 } 358 359 sticky.init = true; 360 } 361 } 362 363 return UI.sticky; 364});
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.