1/** 2 * Sticky.js 3 * Library for sticky elements written in vanilla javascript. With this library you can easily set sticky elements on your website. It's also responsive. 4 * 5 * @version 1.3.0 6 * @author Rafal Galus <[email protected]> 7 * @website https://rgalus.github.io/sticky-js/ 8 * @repo https://github.com/rgalus/sticky-js 9 * @license https://github.com/rgalus/sticky-js/blob/master/LICENSE 10 */ class Sticky{constructor(t="",i={}){this.selector=t,this.elements=[],this.version="1.3.0",this.vp=this.getViewportSize(),this.body=document.querySelector("body"),this.options={wrap:i.wrap||!1,wrapWith:i.wrapWith||"<span></span>",marginTop:i.marginTop||0,marginBottom:i.marginBottom||0,stickyFor:i.stickyFor||0,stickyClass:i.stickyClass||null,stickyContainer:i.stickyContainer||"body"},this.updateScrollTopPosition=this.updateScrollTopPosition.bind(this),this.updateScrollTopPosition(),window.addEventListener("load",this.updateScrollTopPosition),window.addEventListener("scroll",this.updateScrollTopPosition),this.run()}run(){let t=setInterval(()=>{if("complete"===document.readyState){clearInterval(t);let i=document.querySelectorAll(this.selector);this.forEach(i,t=>this.renderElement(t))}},10)}renderElement(t){t.sticky={},t.sticky.active=!1,t.sticky.marginTop=parseInt(t.getAttribute("data-margin-top"))||this.options.marginTop,t.sticky.marginBottom=parseInt(t.getAttribute("data-margin-bottom"))||this.options.marginBottom,t.sticky.stickyFor=parseInt(t.getAttribute("data-sticky-for"))||this.options.stickyFor,t.sticky.stickyClass=t.getAttribute("data-sticky-class")||this.options.stickyClass,t.sticky.wrap=!!t.hasAttribute("data-sticky-wrap")||this.options.wrap,t.sticky.stickyContainer=this.options.stickyContainer,t.sticky.container=this.getStickyContainer(t),t.sticky.container.rect=this.getRectangle(t.sticky.container),t.sticky.rect=this.getRectangle(t),"img"===t.tagName.toLowerCase()&&(t.onload=()=>t.sticky.rect=this.getRectangle(t)),t.sticky.wrap&&this.wrapElement(t),this.activate(t)}wrapElement(t){t.insertAdjacentHTML("beforebegin",t.getAttribute("data-sticky-wrapWith")||this.options.wrapWith),t.previousSibling.appendChild(t)}activate(t){t.sticky.rect.top+t.sticky.rect.height<t.sticky.container.rect.top+t.sticky.container.rect.height&&t.sticky.stickyFor<this.vp.width&&!t.sticky.active&&(t.sticky.active=!0),0>this.elements.indexOf(t)&&this.elements.push(t),t.sticky.resizeEvent||(this.initResizeEvents(t),t.sticky.resizeEvent=!0),t.sticky.scrollEvent||(this.initScrollEvents(t),t.sticky.scrollEvent=!0),this.setPosition(t)}initResizeEvents(t){t.sticky.resizeListener=()=>this.onResizeEvents(t),window.addEventListener("resize",t.sticky.resizeListener)}destroyResizeEvents(t){window.removeEventListener("resize",t.sticky.resizeListener)}onResizeEvents(t){this.vp=this.getViewportSize(),t.sticky.rect=this.getRectangle(t),t.sticky.container.rect=this.getRectangle(t.sticky.container),t.sticky.rect.top+t.sticky.rect.height<t.sticky.container.rect.top+t.sticky.container.rect.height&&t.sticky.stickyFor<this.vp.width&&!t.sticky.active?t.sticky.active=!0:(t.sticky.rect.top+t.sticky.rect.height>=t.sticky.container.rect.top+t.sticky.container.rect.height||t.sticky.stickyFor>=this.vp.width&&t.sticky.active)&&(t.sticky.active=!1),this.setPosition(t)}initScrollEvents(t){t.sticky.scrollListener=()=>this.onScrollEvents(t),window.addEventListener("scroll",t.sticky.scrollListener)}destroyScrollEvents(t){window.removeEventListener("scroll",t.sticky.scrollListener)}onScrollEvents(t){t.sticky&&t.sticky.active&&this.setPosition(t)}setPosition(t){this.css(t,{position:"",width:"",top:"",left:""}),!(this.vp.height<t.sticky.rect.height)&&t.sticky.active&&(t.sticky.rect.width||(t.sticky.rect=this.getRectangle(t)),t.sticky.wrap&&this.css(t.parentNode,{display:"block",width:t.sticky.rect.width+"px",height:t.sticky.rect.height+"px"}),0===t.sticky.rect.top&&t.sticky.container===this.body?(this.css(t,{position:"fixed",top:t.sticky.rect.top+"px",left:t.sticky.rect.left+"px",width:t.sticky.rect.width+"px"}),t.sticky.stickyClass&&t.classList.add(t.sticky.stickyClass)):this.scrollTop>t.sticky.rect.top-t.sticky.marginTop?(this.css(t,{position:"fixed",width:t.sticky.rect.width+"px",left:t.sticky.rect.left+"px"}),this.scrollTop+t.sticky.rect.height+t.sticky.marginTop>t.sticky.container.rect.top+t.sticky.container.offsetHeight-t.sticky.marginBottom?(t.sticky.stickyClass&&t.classList.remove(t.sticky.stickyClass),this.css(t,{top:t.sticky.container.rect.top+t.sticky.container.offsetHeight-(this.scrollTop+t.sticky.rect.height+t.sticky.marginBottom)+"px"})):(t.sticky.stickyClass&&t.classList.add(t.sticky.stickyClass),this.css(t,{top:t.sticky.marginTop+"px"}))):(t.sticky.stickyClass&&t.classList.remove(t.sticky.stickyClass),this.css(t,{position:"",width:"",top:"",left:""}),t.sticky.wrap&&this.css(t.parentNode,{display:"",width:"",height:""})))}update(){this.forEach(this.elements,t=>{t.sticky.rect=this.getRectangle(t),t.sticky.container.rect=this.getRectangle(t.sticky.container),this.activate(t),this.setPosition(t)})}destroy(){window.removeEventListener("load",this.updateScrollTopPosition),window.removeEventListener("scroll",this.updateScrollTopPosition),this.forEach(this.elements,t=>{this.destroyResizeEvents(t),this.destroyScrollEvents(t),delete t.sticky})}getStickyContainer(t){let i=t.parentNode;for(;!i.hasAttribute("data-sticky-container")&&!i.parentNode.querySelector(t.sticky.stickyContainer)&&i!==this.body;)i=i.parentNode;return i}getRectangle(t){this.css(t,{position:"",width:"",top:"",left:""});let i=Math.max(t.offsetWidth,t.clientWidth,t.scrollWidth),s=Math.max(t.offsetHeight,t.clientHeight,t.scrollHeight),e=0,c=0;do e+=t.offsetTop||0,c+=t.offsetLeft||0,t=t.offsetParent;while(t);return{top:e,left:c,width:i,height:s}}getViewportSize(){return{width:Math.max(document.documentElement.clientWidth,window.innerWidth||0),height:Math.max(document.documentElement.clientHeight,window.innerHeight||0)}}updateScrollTopPosition(){this.scrollTop=(window.pageYOffset||document.scrollTop)-(document.clientTop||0)||0}forEach(t,i){for(let s=0,e=t.length;s<e;s++)i(t[s])}css(t,i){for(let s in i)i.hasOwnProperty(s)&&(t.style[s]=i[s])}}((t,i)=>{"undefined"!=typeof exports?module.exports=i:"function"==typeof define&&define.amd?define([],function(){return i}):t.Sticky=i})(this,Sticky);
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.