UNPKG

@odopod/odo-affix

Version:

Makes an element fixed position while its within a container.

3 lines (2 loc) 5.68 kB
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@odopod/odo-window-events"),require("@odopod/odo-scroll-animation")):"function"==typeof define&&define.amd?define(["@odopod/odo-window-events","@odopod/odo-scroll-animation"],e):t.OdoAffix=e(t.OdoWindowEvents,t.OdoScrollAnimation)}(this,function(t,e){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t,e=e&&e.hasOwnProperty("default")?e.default:e;var i=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},o=function(){function t(t,e){for(var i=0;i<e.length;i++){var o=e[i];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,i,o){return i&&t(e.prototype,i),o&&t(e,o),e}}(),s=function(){function t(o){if(i(this,t),this.element=o,this._anchor=document.getElementById(o.getAttribute("data-anchor")),!this._anchor)throw new Error('Unable to find element with id="'+o.getAttribute("data-anchor")+'"');this.isStuck=!1,this.isAtBottom=!1,this.isPromoted=!1,this._getUiOverlap=function(){return 0},this._overlap=0,this._maxHeight=0,this._marginTop=0,this._marginBottom=0,this._top=0,this._bottom=0,this.containerHeight=0,this._scrollId=e.add(this.process.bind(this)),this.element.classList.add(t.Classes.BASE),this.element.style.overflowY="auto",t.instances.push(this),this.update()}return t.prototype.read=function(){var t=this._anchor.getBoundingClientRect(),e=window.pageYOffset,i=window.innerHeight,o=this.element.offsetHeight;this._asideWidth=this.element.offsetWidth;var s=getComputedStyle(this.element,null);this._marginTop=parseFloat(s.marginTop),this._marginBottom=parseFloat(s.marginBottom),this._overlap=this._getUiOverlap(),this._maxHeight=i-this._overlap-this._marginTop-this._marginBottom,this.containerHeight=Math.round(t.height),this._top=t.top+e,this._bottom=t.bottom+e-Math.min(o,this._maxHeight)},t.prototype.write=function(){this.element.style.maxHeight=this._maxHeight+"px",this.element.style.width=this._asideWidth+"px"},t.prototype.process=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:window.pageYOffset;!this.isStuck&&t>=this.top&&t<this.bottom||this.isAtBottom&&t<this.bottom?this.stick():!this.isAtBottom&&t>=this.bottom?this.stickToBottom():this.isStuck&&t<this.top&&this.unstick();var e=this.isInPromotionRange(t);!this.isPromoted&&e?this.layerPromote():this.isPromoted&&!e&&this.layerDemote()},t.prototype.isInPromotionRange=function(e){return e>=this.top-t.PROMOTION_RANGE&&e<=this.bottom+t.PROMOTION_RANGE},t.prototype.stick=function(){this.element.style.position="fixed",this.element.style.top=Math.round(this._overlap)+"px",this.element.classList.remove(t.Classes.AT_BOTTOM),this.element.classList.remove(t.Classes.AT_TOP),this.isStuck=!0,this.isAtBottom=!1},t.prototype.stickToBottom=function(){this.element.style.position="absolute",this.element.style.top=Math.round(this._bottom-this._top-this._marginBottom)+"px",this.element.classList.remove(t.Classes.AT_TOP),this.element.classList.add(t.Classes.AT_BOTTOM),this.isAtBottom=!0},t.prototype.unstick=function(){this.element.style.position="",this.element.classList.add(t.Classes.AT_TOP),this.element.classList.remove(t.Classes.AT_BOTTOM),this.isStuck=!1,this.isAtBottom=!1},t.prototype.layerPromote=function(){this.element.style.willChange="position",this.element.style.transform="translateZ(0)",this.isPromoted=!0},t.prototype.layerDemote=function(){this.element.style.willChange="",this.element.style.transform="",this.isPromoted=!1},t.prototype.reset=function(){this.element.style.maxHeight="",this.element.style.width=""},t.prototype.update=function(){var t=this.element.scrollTop;this.unstick(),this.reset(),this.read(),this.write(),this.process(),this.element.scrollTop=t},t.prototype.dispose=function(){this.layerDemote(),this.element.classList.remove(t.Classes.BASE),this.element.style.position="",this.element.style.top="",this.element.style.maxHeight="",this.element.style.width="",this.element.style.overflowY="",this.element=null,this._anchor=null,e.remove(this._scrollId),t.arrayRemove(t.instances,this)},t._addImageLoadHandlers=function(){for(var e=document.getElementsByTagName("img"),i=0,o=e.length;i<o;i++)e[i].addEventListener("load",t._scheduleUpdate,!1)},t._scheduleUpdate=function(){window.removeEventListener("load",t._scheduleUpdate),t._updateId&&window.cancelAnimationFrame(t._updateId),t._updateId=window.requestAnimationFrame(t._handleImageLoad)},t._handleImageLoad=function(){t._updateId=null,t.documentHeight=document.body.offsetHeight,t.viewportHeight=window.innerHeight,t.update()},t.update=function(){var e=window.pageYOffset,i=t.instances.map(function(t){return t.element.scrollTop});t.instances.forEach(function(t){t.unstick(),t.reset()}),t.instances.forEach(function(t){t.read()}),t.instances.forEach(function(t){t.write(),t.process(e)}),t.instances.forEach(function(t,e){t.element.scrollTop=i[e]})},t.arrayRemove=function(t,e){var i=t.indexOf(e);return t.splice(i,1),e},o(t,[{key:"uiOverlap",get:function(){return this._getUiOverlap},set:function(t){this._getUiOverlap=t,this.update()}},{key:"top",get:function(){return this._top-this._overlap}},{key:"bottom",get:function(){return this._bottom-this._marginBottom}}]),t}();return s.PROMOTION_RANGE=200,s.instances=[],s._updateId=null,s.documentHeight=document.body.offsetHeight,s.viewportHeight=window.innerHeight,s._addImageLoadHandlers(),s._resizeId=t.onResize(s._scheduleUpdate),window.addEventListener("load",s._scheduleUpdate),s.Classes={BASE:"odo-affix",AT_TOP:"odo-affix--at-top",AT_BOTTOM:"odo-affix--at-bottom"},s}); //# sourceMappingURL=odo-affix.min.js.map