1 2/** 3 stickybits - Stickybits is a lightweight alternative to `position: sticky` polyfills 4 @version v3.6.1 5 @link https://github.com/dollarshaveclub/stickybits#readme 6 @author Jeff Wainwright <[email protected]> (https://jeffry.in) 7 @license MIT 8**/ 9(function (global, factory) { 10 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 11 typeof define === 'function' && define.amd ? define(factory) : 12 (global = global || self, global.stickybits = factory()); 13}(this, function () { 'use strict'; 14 15 /* 16 STICKYBITS ð 17 -------- 18 > a lightweight alternative to `position: sticky` polyfills ð¬ 19 -------- 20 - each method is documented above it our view the readme 21 - Stickybits does not manage polymorphic functionality (position like properties) 22 * polymorphic functionality: (in the context of describing Stickybits) 23 means making things like `position: sticky` be loosely supported with position fixed. 24 It also means that features like `useStickyClasses` takes on styles like `position: fixed`. 25 -------- 26 defaults ð 27 -------- 28 - version = `package.json` version 29 - userAgent = viewer browser agent 30 - target = DOM element selector 31 - noStyles = boolean 32 - offset = number 33 - parentClass = 'string' 34 - scrollEl = window || DOM element selector || DOM element 35 - stickyClass = 'string' 36 - stuckClass = 'string' 37 - useStickyClasses = boolean 38 - useFixed = boolean 39 - useGetBoundingClientRect = boolean 40 - verticalPosition = 'string' 41 -------- 42 propsð 43 -------- 44 - p = props {object} 45 -------- 46 instance note 47 -------- 48 - stickybits parent methods return this 49 - stickybits instance methods return an instance item 50 -------- 51 nomenclature 52 -------- 53 - target => el => e 54 - props => o || p 55 - instance => item => it 56 -------- 57 methods 58 -------- 59 - .definePosition = defines sticky or fixed 60 - .addInstance = an array of objects for each Stickybits Target 61 - .getClosestParent = gets the parent for non-window scroll 62 - .getTopPosition = gets the element top pixel position from the viewport 63 - .computeScrollOffsets = computes scroll position 64 - .toggleClasses = older browser toggler 65 - .manageState = manages sticky state 66 - .removeClass = older browser support class remover 67 - .removeInstance = removes an instance 68 - .cleanup = removes all Stickybits instances and cleans up dom from stickybits 69 */ 70 var Stickybits = 71 /*#__PURE__*/ 72 function () { 73 function Stickybits(target, obj) { 74 var o = typeof obj !== 'undefined' ? obj : {}; 75 this.version = '3.6.1'; 76 this.userAgent = window.navigator.userAgent || 'no `userAgent` provided by the browser'; 77 this.props = { 78 customStickyChangeNumber: o.customStickyChangeNumber || null, 79 noStyles: o.noStyles || false, 80 stickyBitStickyOffset: o.stickyBitStickyOffset || 0, 81 parentClass: o.parentClass || 'js-stickybit-parent', 82 scrollEl: typeof o.scrollEl === 'string' ? document.querySelector(o.scrollEl) : o.scrollEl || window, 83 stickyClass: o.stickyClass || 'js-is-sticky', 84 stuckClass: o.stuckClass || 'js-is-stuck', 85 stickyChangeClass: o.stickyChangeClass || 'js-is-sticky--change', 86 useStickyClasses: o.useStickyClasses || false, 87 useFixed: o.useFixed || false, 88 useGetBoundingClientRect: o.useGetBoundingClientRect || false, 89 verticalPosition: o.verticalPosition || 'top' 90 /* 91 define positionVal 92 ---- 93 - uses a computed (`.definePosition()`) 94 - defined the position 95 */ 96 97 }; 98 this.props.positionVal = this.definePosition() || 'fixed'; 99 this.instances = []; 100 var _this$props = this.props, 101 positionVal = _this$props.positionVal, 102 verticalPosition = _this$props.verticalPosition, 103 noStyles = _this$props.noStyles, 104 stickyBitStickyOffset = _this$props.stickyBitStickyOffset,
105 useStickyClasses = _this$props.useStickyClasses; 106 var verticalPositionStyle = verticalPosition === 'top' && !noStyles ? stickyBitStickyOffset + "px" : ''; 107 var positionStyle = positionVal !== 'fixed' ? positionVal : ''; 108 this.els = typeof target === 'string' ? document.querySelectorAll(target) : target; 109 if (!('length' in this.els)) this.els = [this.els]; 110 111 for (var i = 0; i < this.els.length; i++) { 112 var el = this.els[i]; // set vertical position 113 114 el.style[verticalPosition] = verticalPositionStyle; 115 el.style.position = positionStyle; 116 117 if (positionVal === 'fixed' || useStickyClasses) { 118 var instance = this.addInstance(el, this.props); // instances are an array of objects 119 120 this.instances.push(instance); 121 } 122 } 123 } 124 /* 125 setStickyPosition âï¸ 126 -------- 127 â most basic thing stickybits does 128 => checks to see if position sticky is supported 129 => defined the position to be used 130 => stickybits works accordingly 131 */ 132 133 134 var _proto = Stickybits.prototype; 135 136 _proto.definePosition = function definePosition() { 137 var stickyProp; 138 139 if (this.props.useFixed) { 140 stickyProp = 'fixed'; 141 } else { 142 var prefix = ['', '-o-', '-webkit-', '-moz-', '-ms-']; 143 var test = document.head.style; 144 145 for (var i = 0; i < prefix.length; i += 1) { 146 test.position = prefix[i] + "sticky"; 147 } 148 149 stickyProp = test.position ? test.position : 'fixed'; 150 test.position = ''; 151 } 152 153 return stickyProp; 154 } 155 /* 156 addInstance âï¸ 157 -------- 158 â manages instances of items 159 - takes in an el and props 160 - returns an item object 161 --- 162 - target = el 163 - o = {object} = props 164 - scrollEl = 'string' | object 165 - verticalPosition = number 166 - off = boolean 167 - parentClass = 'string' 168 - stickyClass = 'string' 169 - stuckClass = 'string' 170 --- 171 - defined later 172 - parent = dom element 173 - state = 'string' 174 - offset = number 175 - stickyStart = number 176 - stickyStop = number 177 - returns an instance object 178 */ 179 ; 180 181 _proto.addInstance = function addInstance(el, props) { 182 var _this = this; 183 184 var item = { 185 el: el, 186 parent: el.parentNode, 187 props: props 188 }; 189 this.isWin = this.props.scrollEl === window; 190 var se = this.isWin ? window : this.getClosestParent(item.el, item.props.scrollEl); 191 this.computeScrollOffsets(item); 192 item.parent.className += " " + props.parentClass; 193 item.state = 'default'; 194 195 item.stateContainer = function () { 196 return _this.manageState(item); 197 }; 198 199 se.addEventListener('scroll', item.stateContainer); 200 return item; 201 } 202 /* 203 -------- 204 getParent ð¨â 205 -------- 206 - a helper function that gets the target element's parent selected el 207 - only used for non `window` scroll elements 208 - supports older browsers 209 */ 210 ; 211 212 _proto.getClosestParent = function getClosestParent(el, match) { 213 // p = parent element 214 var p = match; 215 var e = el; 216 if (e.parentElement === p) return p; // traverse up the dom tree until we get to the parent 217 218 while (e.parentElement !== p) { 219 e = e.parentElement; 220 } // return parent element 221 222 223 return p; 224 } 225 /* 226 -------- 227 getTopPosition 228 -------- 229 - a helper function that gets the topPosition of a Stickybit element 230 - from the top level of the DOM 231 */ 232 ; 233 234 _proto.getTopPosition = function getTopPosition(el) { 235 if (this.props.useGetBoundingClientRect) { 236 return el.getBoundingClientRect().top + (this.props.scrollEl.pageYOffset || document.documentElement.scrollTop); 237 } 238 239 var topPosition = 0; 240 241 do { 242 topPosition = el.offsetTop + topPosition; 243 } while (el = el.offsetParent); 244 245 return topPosition; 246 } 247 /* 248 computeScrollOffsets ð 249 --- 250 computeScrollOffsets for Stickybits 251 - defines 252 - offset 253 - start 254 - stop 255 */ 256 ; 257 258 _proto.computeScrollOffsets = function computeScrollOffsets(item) { 259 var it = item; 260 var p = it.props; 261 var el = it.el; 262 var parent = it.parent; 263 var isCustom = !this.isWin && p.positionVal === 'fixed'; 264 var isTop = p.verticalPosition !== 'bottom'; 265 var scrollElOffset = isCustom ? this.getTopPosition(p.scrollEl) : 0; 266 var stickyStart = isCustom ? this.getTopPosition(parent) - scrollElOffset : this.getTopPosition(parent); 267 var stickyChangeOffset = p.customStickyChangeNumber !== null ? p.customStickyChangeNumber : el.offsetHeight; 268 var parentBottom = stickyStart + parent.offsetHeight; 269 it.offset = scrollElOffset + p.stickyBitStickyOffset; 270 it.stickyStart = isTop ? stickyStart - it.offset : 0; 271 it.stickyChange = it.stickyStart + stickyChangeOffset; 272 it.stickyStop = isTop ? parentBottom - (el.offsetHeight + it.offset) : parentBottom - window.innerHeight; 273 return it; 274 } 275 /* 276 toggleClasses âï¸ 277 --- 278 toggles classes (for older browser support) 279 r = removed class 280 a = added class 281 */ 282 ; 283 284 _proto.toggleClasses = function toggleClasses(el, r, a) { 285 var e = el; 286 var cArray = e.className.split(' '); 287 if (a && cArray.indexOf(a) === -1) cArray.push(a); 288 var rItem = cArray.indexOf(r); 289 if (rItem !== -1) cArray.splice(rItem, 1); 290 e.className = cArray.join(' '); 291 } 292 /* 293 manageState ð 294 --- 295 - defines the state 296 - normal 297 - sticky 298 - stuck 299 */ 300 ; 301 302 _proto.manageState = function manageState(item) { 303 // cache object 304 var it = item; 305 var e = it.el; 306 var p = it.props; 307 var state = it.state; 308 var start = it.stickyStart; 309 var change = it.stickyChange; 310 var stop = it.stickyStop; 311 var stl = e.style; // cache props 312 313 var ns = p.noStyles; 314 var pv = p.positionVal; 315 var se = p.scrollEl; 316 var sticky = p.stickyClass; 317 var stickyChange = p.stickyChangeClass; 318 var stuck = p.stuckClass; 319 var vp = p.verticalPosition; 320 var isTop = vp !== 'bottom'; 321 /* 322 requestAnimationFrame 323 --- 324 - use rAF 325 - or stub rAF 326 */ 327 328 var rAFStub = function rAFDummy(f) { 329 f(); 330 }; 331 332 var rAF = !this.isWin ? rAFStub : window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || rAFStub; 333 /* 334 define scroll vars 335 --- 336 - scroll 337 - notSticky 338 - isSticky 339 - isStuck 340 */ 341 342 var tC = this.toggleClasses; 343 var scroll = this.isWin ? window.scrollY || window.pageYOffset : se.scrollTop; 344 var notSticky = scroll > start && scroll < stop && (state === 'default' || state === 'stuck'); 345 var isSticky = isTop && scroll <= start && (state === 'sticky' || state === 'stuck'); 346 var isStuck = scroll >= stop && state === 'sticky'; 347 /* 348 Unnamed arrow functions within this block 349 --- 350 - help wanted or discussion 351 - view test.stickybits.js 352 - `stickybits .manageState `position: fixed` interface` for more awareness ð 353 */ 354 355 if (notSticky) { 356 it.state = 'sticky'; 357 rAF(function () { 358 tC(e, stuck, sticky); 359 stl.position = pv; 360 if (ns) return; 361 stl.bottom = ''; 362 stl[vp] = p.stickyBitStickyOffset + "px"; 363 }); 364 } else if (isSticky) { 365 it.state = 'default'; 366 rAF(function () { 367 tC(e, sticky); 368 tC(e, stuck); 369 if (pv === 'fixed') stl.position = ''; 370 }); 371 } else if (isStuck) { 372 it.state = 'stuck'; 373 rAF(function () { 374 tC(e, sticky, stuck); 375 if (pv !== 'fixed' || ns) return; 376 stl.top = ''; 377 stl.bottom = '0'; 378 stl.position = 'absolute'; 379 }); 380 } 381 382 var isStickyChange = scroll >= change && scroll <= stop; 383 var isNotStickyChange = scroll < change / 2 || scroll > stop; 384 var stub = 'stub'; // a stub css class to remove 385 386 if (isNotStickyChange) { 387 rAF(function () { 388 tC(e, stickyChange); 389 }); 390 } else if (isStickyChange) { 391 rAF(function () { 392 tC(e, stub, stickyChange); 393 }); 394 } 395 396 return it; 397 }; 398 399 _proto.update = function update(updatedProps) { 400 if (updatedProps === void 0) { 401 updatedProps = null; 402 } 403 404 for (var i = 0; i < this.instances.length; i += 1) { 405 var instance = this.instances[i]; 406 this.computeScrollOffsets(instance); 407 408 if (updatedProps) { 409 for (var updatedProp in updatedProps) { 410 instance.props[updatedProp] = updatedProps[updatedProp]; 411 } 412 } 413 } 414 415 return this; 416 } 417 /* 418 removes an instance ð 419 -------- 420 - cleanup instance 421 */ 422 ; 423 424 _proto.removeInstance = function removeInstance(instance) { 425 var e = instance.el; 426 var p = instance.props; 427 var tC = this.toggleClasses; 428 e.style.position = ''; 429 e.style[p.verticalPosition] = ''; 430 tC(e, p.stickyClass); 431 tC(e, p.stuckClass); 432 tC(e.parentNode, p.parentClass); 433 } 434 /* 435 cleanup ð 436 -------- 437 - cleans up each instance 438 - clears instance 439 */ 440 ; 441 442 _proto.cleanup = function cleanup() { 443 for (var i = 0; i < this.instances.length; i += 1) { 444 var instance = this.instances[i]; 445 instance.props.scrollEl.removeEventListener('scroll', instance.stateContainer); 446 this.removeInstance(instance); 447 } 448 449 this.manageState = false; 450 this.instances = []; 451 }; 452 453 return Stickybits; 454 }(); 455 /* 456 export 457 -------- 458 exports StickBits to be used ð 459 */ 460 461 462 function stickybits(target, o) { 463 return new Stickybits(target, o); 464 } 465 466 return stickybits; 467 468})); 469 470 471jQuery(function() { 472 473 var stickybit = []; 474 //dont enable when page builder is active, and check that there is a data-sticky attribute
475 if(!jQuery('body').hasClass('fl-builder-edit') && jQuery("[bt-sticky='true']").length) 476 { 477 var stickyItems = jQuery("[bt-sticky='true']"); 478 479 if(stickyItems.length !== 0){ 480 //check for overflow visible on all parents and fix 481 jQuery('[bt-sticky]').parents().each(function(){ 482 if(jQuery(this).css("overflow") != "visible") 483 { 484 console.log("Sticky Column Notice: CSS Sticky position requires all parent elements to have overflow:visible. We detected one below that does not have that setting. Not to worry, we have updated them automatically."); 485 console.log(jQuery(this)); 486 console.log("overflow: " + jQuery(this).css('overflow') + ", changed to... overflow:visible"); 487 jQuery(this).css("overflow","visible"); 488 } 489 }); 490 491 stickyItems.each(function(index, item){ 492 493 // get the offset 494 var topPadding = parseInt(jQuery(item).attr('bt-sticky-top-margin')); 495 var stickyItem = jQuery(item); 496 497 //target the parent if its a nested col, then we target the parent 498 if(stickyItem.parent().hasClass('fl-col-group-nested')) 499 stickyItem = stickyItem.parent(); 500 501 stickybit[jQuery(item).attr('data-node')] = stickybits(stickyItem,{ 502 stickyBitStickyOffset: topPadding, 503 useStickyClasses: true, 504 stickyClass: 'bt-sticking', 505 stuckClass: 'bt-stuck', 506 }); 507 }); 508 } 509 } 510}); 511 512 513 514
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.