From a2264b809bb5ec6a232d250ce13920d4b5a69de8 Mon Sep 17 00:00:00 2001 From: abouolia Date: Sun, 4 Feb 2018 13:58:31 +0200 Subject: [PATCH 1/4] Re-build the bundle. --- dist/jquery.sticky-sidebar.js | 1254 ++++++++++++++--------------- dist/jquery.sticky-sidebar.js.map | 2 +- dist/jquery.sticky-sidebar.min.js | 2 +- dist/sticky-sidebar.js | 1187 +++++++++++++-------------- dist/sticky-sidebar.js.map | 2 +- dist/sticky-sidebar.min.js | 2 +- 6 files changed, 1164 insertions(+), 1285 deletions(-) diff --git a/dist/jquery.sticky-sidebar.js b/dist/jquery.sticky-sidebar.js index 14a14cb..2db7654 100644 --- a/dist/jquery.sticky-sidebar.js +++ b/dist/jquery.sticky-sidebar.js @@ -1,368 +1,376 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : - (factory()); + (global.StickySidebar = factory()); }(this, (function () { 'use strict'; -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); +var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -/** - * Sticky Sidebar JavaScript Plugin. - * @version 3.3.1 - * @author Ahmed Bouhuolia - * @license The MIT License (MIT) - */ -var StickySidebar = function () { - // --------------------------------- - // # Define Constants - // --------------------------------- - // - var EVENT_KEY = '.stickySidebar'; - var DEFAULTS = { +function unwrapExports (x) { + return x && x.__esModule ? x['default'] : x; +} - /** - * Additional top spacing of the element when it becomes sticky. - * @type {Numeric|Function} - */ - topSpacing: 0, - - /** - * Additional bottom spacing of the element when it becomes sticky. - * @type {Numeric|Function} - */ - bottomSpacing: 0, +function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; +} - /** - * Container sidebar selector to know what the beginning and end of sticky element. - * @type {String|False} - */ - containerSelector: false, +var stickySidebar = createCommonjsModule(function (module, exports) { +(function (global, factory) { + if (typeof undefined === "function" && undefined.amd) { + undefined(['exports'], factory); + } else { + factory(exports); + } +})(commonjsGlobal, function (exports) { + 'use strict'; - /** - * Inner wrapper selector. - * @type {String} - */ - innerWrapperSelector: '.inner-wrapper-sticky', + Object.defineProperty(exports, "__esModule", { + value: true + }); - /** - * The name of CSS class to apply to elements when they have become stuck. - * @type {String|False} - */ - stickyClass: 'is-affixed', + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } - /** - * Detect when sidebar and its container change height so re-calculate their dimensions. - * @type {Boolean} - */ - resizeSensor: true, + var _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } - /** - * The sidebar returns to its normal position if its width below this value. - * @type {Numeric} - */ - minWidth: false - }; + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); - // --------------------------------- - // # Class Definition - // --------------------------------- - // /** - * Sticky Sidebar Class. - * @public + * Sticky Sidebar JavaScript Plugin. + * @version 3.3.1 + * @author Ahmed Bouhuolia + * @license The MIT License (MIT) */ - var StickySidebar = function () { - /** - * Sticky Sidebar Constructor. - * @constructor - * @param {HTMLElement|String} sidebar - The sidebar element or sidebar selector. - * @param {Object} options - The options of sticky sidebar. - */ - function StickySidebar(sidebar) { - var _this = this; - - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - _classCallCheck(this, StickySidebar); - - this.options = StickySidebar.extend(DEFAULTS, options); + // --------------------------------- + // # Define Constants + // --------------------------------- + // + var EVENT_KEY = '.stickySidebar'; + var DEFAULTS = { + /** + * Additional top spacing of the element when it becomes sticky. + * @type {Numeric|Function} + */ + topSpacing: 0, - // Sidebar element query if there's no one, throw error. - this.sidebar = 'string' === typeof sidebar ? document.querySelector(sidebar) : sidebar; - if ('undefined' === typeof this.sidebar) throw new Error("There is no specific sidebar element."); + /** + * Additional bottom spacing of the element when it becomes sticky. + * @type {Numeric|Function} + */ + bottomSpacing: 0, - this.sidebarInner = false; - this.container = this.sidebar.parentElement; + /** + * Container sidebar selector to know what the beginning and end of sticky element. + * @type {String|False} + */ + containerSelector: false, - // Current Affix Type of sidebar element. - this.affixedType = 'STATIC'; - this.direction = 'down'; - this.support = { - transform: false, - transform3d: false - }; + /** + * Inner wrapper selector. + * @type {String} + */ + innerWrapperSelector: '.inner-wrapper-sticky', - this._initialized = false; - this._reStyle = false; - this._breakpoint = false; - this._resizeListeners = []; - - // Dimensions of sidebar, container and screen viewport. - this.dimensions = { - translateY: 0, - topSpacing: 0, - lastTopSpacing: 0, - bottomSpacing: 0, - lastBottomSpacing: 0, - sidebarHeight: 0, - sidebarWidth: 0, - containerTop: 0, - containerHeight: 0, - viewportHeight: 0, - viewportTop: 0, - lastViewportTop: 0 - }; + /** + * The name of CSS class to apply to elements when they have become stuck. + * @type {String|False} + */ + stickyClass: 'is-affixed', - // Bind event handlers for referencability. - ['handleEvent'].forEach(function (method) { - _this[method] = _this[method].bind(_this); - }); + /** + * Detect when sidebar and its container change height so re-calculate their dimensions. + * @type {Boolean} + */ + resizeSensor: true, - // Initialize sticky sidebar for first time. - this.initialize(); - } + /** + * The sidebar returns to its normal position if its width below this value. + * @type {Numeric} + */ + minWidth: false + }; + // --------------------------------- + // # Class Definition + // --------------------------------- + // /** - * Initializes the sticky sidebar by adding inner wrapper, define its container, - * min-width breakpoint, calculating dimensions, adding helper classes and inline style. - * @private + * Sticky Sidebar Class. + * @public */ + var StickySidebar = function () { - _createClass(StickySidebar, [{ - key: 'initialize', - value: function initialize() { - var _this2 = this; - - this._setSupportFeatures(); - - // Get sticky sidebar inner wrapper, if not found, will create one. - if (this.options.innerWrapperSelector) { - this.sidebarInner = this.sidebar.querySelector(this.options.innerWrapperSelector); - - if (null === this.sidebarInner) this.sidebarInner = false; - } - - if (!this.sidebarInner) { - var wrapper = document.createElement('div'); - wrapper.setAttribute('class', 'inner-wrapper-sticky'); - this.sidebar.appendChild(wrapper); - - while (this.sidebar.firstChild != wrapper) { - wrapper.appendChild(this.sidebar.firstChild); - }this.sidebarInner = this.sidebar.querySelector('.inner-wrapper-sticky'); - } - - // Container wrapper of the sidebar. - if (this.options.containerSelector) { - var containers = document.querySelectorAll(this.options.containerSelector); - containers = Array.prototype.slice.call(containers); - - containers.forEach(function (container, item) { - if (!container.contains(_this2.sidebar)) return; - _this2.container = container; - }); - - if (!containers.length) throw new Error("The container does not contains on the sidebar."); - } - - // If top/bottom spacing is not function parse value to integer. - if ('function' !== typeof this.options.topSpacing) this.options.topSpacing = parseInt(this.options.topSpacing) || 0; - - if ('function' !== typeof this.options.bottomSpacing) this.options.bottomSpacing = parseInt(this.options.bottomSpacing) || 0; - - // Breakdown sticky sidebar if screen width below `options.minWidth`. - this._widthBreakpoint(); - - // Calculate dimensions of sidebar, container and viewport. - this.calcDimensions(); - - // Affix sidebar in proper position. - this.stickyPosition(); - - // Bind all events. - this.bindEvents(); + /** + * Sticky Sidebar Constructor. + * @constructor + * @param {HTMLElement|String} sidebar - The sidebar element or sidebar selector. + * @param {Object} options - The options of sticky sidebar. + */ + function StickySidebar(sidebar) { + var _this = this; + + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, StickySidebar); + + this.options = StickySidebar.extend(DEFAULTS, options); + + // Sidebar element query if there's no one, throw error. + this.sidebar = 'string' === typeof sidebar ? document.querySelector(sidebar) : sidebar; + if ('undefined' === typeof this.sidebar) throw new Error("There is no specific sidebar element."); + + this.sidebarInner = false; + this.container = this.sidebar.parentElement; + + // Current Affix Type of sidebar element. + this.affixedType = 'STATIC'; + this.direction = 'down'; + this.support = { + transform: false, + transform3d: false + }; + + this._initialized = false; + this._reStyle = false; + this._breakpoint = false; + + // Dimensions of sidebar, container and screen viewport. + this.dimensions = { + translateY: 0, + maxTranslateY: 0, + topSpacing: 0, + lastTopSpacing: 0, + bottomSpacing: 0, + lastBottomSpacing: 0, + sidebarHeight: 0, + sidebarWidth: 0, + containerTop: 0, + containerHeight: 0, + viewportHeight: 0, + viewportTop: 0, + lastViewportTop: 0 + }; + + // Bind event handlers for referencability. + ['handleEvent'].forEach(function (method) { + _this[method] = _this[method].bind(_this); + }); - // Inform other properties the sticky sidebar is initialized. - this._initialized = true; + // Initialize sticky sidebar for first time. + this.initialize(); } /** - * Bind all events of sticky sidebar plugin. - * @protected + * Initializes the sticky sidebar by adding inner wrapper, define its container, + * min-width breakpoint, calculating dimensions, adding helper classes and inline style. + * @private */ - }, { - key: 'bindEvents', - value: function bindEvents() { - window.addEventListener('resize', this, { passive: true, capture: false }); - window.addEventListener('scroll', this, { passive: true, capture: false }); - this.sidebar.addEventListener('update' + EVENT_KEY, this); + _createClass(StickySidebar, [{ + key: 'initialize', + value: function initialize() { + var _this2 = this; - if (this.options.resizeSensor && 'undefined' !== typeof ResizeSensor) { - new ResizeSensor(this.sidebarInner, this.handleEvent); - new ResizeSensor(this.container, this.handleEvent); - } - } + this._setSupportFeatures(); - /** - * Handles all events of the plugin. - * @param {Object} event - Event object passed from listener. - */ + // Get sticky sidebar inner wrapper, if not found, will create one. + if (this.options.innerWrapperSelector) { + this.sidebarInner = this.sidebar.querySelector(this.options.innerWrapperSelector); - }, { - key: 'handleEvent', - value: function handleEvent(event) { - this.updateSticky(event); - } + if (null === this.sidebarInner) this.sidebarInner = false; + } - /** - * Calculates dimensions of sidebar, container and screen viewpoint - * @public - */ + if (!this.sidebarInner) { + var wrapper = document.createElement('div'); + wrapper.setAttribute('class', 'inner-wrapper-sticky'); + this.sidebar.appendChild(wrapper); - }, { - key: 'calcDimensions', - value: function calcDimensions() { - if (this._breakpoint) return; - var dims = this.dimensions; + while (this.sidebar.firstChild != wrapper) { + wrapper.appendChild(this.sidebar.firstChild); + }this.sidebarInner = this.sidebar.querySelector('.inner-wrapper-sticky'); + } - // Container of sticky sidebar dimensions. - dims.containerTop = StickySidebar.offsetRelative(this.container).top; - dims.containerHeight = this.container.clientHeight; - dims.containerBottom = dims.containerTop + dims.containerHeight; + // Container wrapper of the sidebar. + if (this.options.containerSelector) { + var containers = document.querySelectorAll(this.options.containerSelector); + containers = Array.prototype.slice.call(containers); - // Sidebar dimensions. - dims.sidebarHeight = this.sidebarInner.offsetHeight; - dims.sidebarWidth = this.sidebarInner.offsetWidth; + containers.forEach(function (container, item) { + if (!container.contains(_this2.sidebar)) return; + _this2.container = container; + }); - // Screen viewport dimensions. - dims.viewportHeight = window.innerHeight; + if (!containers.length) throw new Error("The container does not contains on the sidebar."); + } - this._calcDimensionsWithScroll(); - } + // If top/bottom spacing is not function parse value to integer. + if ('function' !== typeof this.options.topSpacing) this.options.topSpacing = parseInt(this.options.topSpacing) || 0; - /** - * Some dimensions values need to be up-to-date when scrolling the page. - * @private - */ + if ('function' !== typeof this.options.bottomSpacing) this.options.bottomSpacing = parseInt(this.options.bottomSpacing) || 0; - }, { - key: '_calcDimensionsWithScroll', - value: function _calcDimensionsWithScroll() { - var dims = this.dimensions; + // Breakdown sticky sidebar if screen width below `options.minWidth`. + this._widthBreakpoint(); - dims.sidebarLeft = StickySidebar.offsetRelative(this.sidebar).left; + // Calculate dimensions of sidebar, container and viewport. + this.calcDimensions(); - dims.viewportTop = document.documentElement.scrollTop || document.body.scrollTop; - dims.viewportBottom = dims.viewportTop + dims.viewportHeight; - dims.viewportLeft = document.documentElement.scrollLeft || document.body.scrollLeft; + // Affix sidebar in proper position. + this.stickyPosition(); - dims.topSpacing = this.options.topSpacing; - dims.bottomSpacing = this.options.bottomSpacing; + // Bind all events. + this.bindEvents(); - if ('function' === typeof dims.topSpacing) dims.topSpacing = parseInt(dims.topSpacing(this.sidebar)) || 0; + // Inform other properties the sticky sidebar is initialized. + this._initialized = true; + } + }, { + key: 'bindEvents', + value: function bindEvents() { + window.addEventListener('resize', this, { passive: true, capture: false }); + window.addEventListener('scroll', this, { passive: true, capture: false }); - if ('function' === typeof dims.bottomSpacing) dims.bottomSpacing = parseInt(dims.bottomSpacing(this.sidebar)) || 0; + this.sidebar.addEventListener('update' + EVENT_KEY, this); - if ('VIEWPORT-TOP' === this.affixedType) { - // Adjust translate Y in the case decrease top spacing value. - if (dims.topSpacing < dims.lastTopSpacing) { - dims.translateY += dims.lastTopSpacing - dims.topSpacing; - this._reStyle = true; - } - } else if ('VIEWPORT-BOTTOM' === this.affixedType) { - // Adjust translate Y in the case decrease bottom spacing value. - if (dims.bottomSpacing < dims.lastBottomSpacing) { - dims.translateY += dims.lastBottomSpacing - dims.bottomSpacing; - this._reStyle = true; + if (this.options.resizeSensor && 'undefined' !== typeof ResizeSensor) { + new ResizeSensor(this.sidebarInner, this.handleEvent); + new ResizeSensor(this.container, this.handleEvent); } } + }, { + key: 'handleEvent', + value: function handleEvent(event) { + this.updateSticky(event); + } + }, { + key: 'calcDimensions', + value: function calcDimensions() { + if (this._breakpoint) return; + var dims = this.dimensions; - dims.lastTopSpacing = dims.topSpacing; - dims.lastBottomSpacing = dims.bottomSpacing; - } + // Container of sticky sidebar dimensions. + dims.containerTop = StickySidebar.offsetRelative(this.container).top; + dims.containerHeight = this.container.clientHeight; + dims.containerBottom = dims.containerTop + dims.containerHeight; - /** - * Determine whether the sidebar is bigger than viewport. - * @public - * @return {Boolean} - */ + // Sidebar dimensions. + dims.sidebarHeight = this.sidebarInner.offsetHeight; + dims.sidebarWidth = this.sidebarInner.offsetWidth; - }, { - key: 'isSidebarFitsViewport', - value: function isSidebarFitsViewport() { - return this.dimensions.sidebarHeight < this.dimensions.viewportHeight; - } + // Screen viewport dimensions. + dims.viewportHeight = window.innerHeight; - /** - * Observe browser scrolling direction top and down. - */ + // Maximum sidebar translate Y. + dims.maxTranslateY = dims.containerHeight - dims.sidebarHeight; - }, { - key: 'observeScrollDir', - value: function observeScrollDir() { - var dims = this.dimensions; - if (dims.lastViewportTop === dims.viewportTop) return; + this._calcDimensionsWithScroll(); + } + }, { + key: '_calcDimensionsWithScroll', + value: function _calcDimensionsWithScroll() { + var dims = this.dimensions; - var furthest = 'down' === this.direction ? Math.min : Math.max; + dims.sidebarLeft = StickySidebar.offsetRelative(this.sidebar).left; - // If the browser is scrolling not in the same direction. - if (dims.viewportTop === furthest(dims.viewportTop, dims.lastViewportTop)) this.direction = 'down' === this.direction ? 'up' : 'down'; - } + dims.viewportTop = document.documentElement.scrollTop || document.body.scrollTop; + dims.viewportBottom = dims.viewportTop + dims.viewportHeight; + dims.viewportLeft = document.documentElement.scrollLeft || document.body.scrollLeft; - /** - * Gets affix type of sidebar according to current scrollTop and scrollLeft. - * Holds all logical affix of the sidebar when scrolling up and down and when sidebar - * is bigger than viewport and vice versa. - * @public - * @return {String|False} - Proper affix type. - */ + dims.topSpacing = this.options.topSpacing; + dims.bottomSpacing = this.options.bottomSpacing; - }, { - key: 'getAffixType', - value: function getAffixType() { - var dims = this.dimensions, - affixType = false; + if ('function' === typeof dims.topSpacing) dims.topSpacing = parseInt(dims.topSpacing(this.sidebar)) || 0; - this._calcDimensionsWithScroll(); + if ('function' === typeof dims.bottomSpacing) dims.bottomSpacing = parseInt(dims.bottomSpacing(this.sidebar)) || 0; - var sidebarBottom = dims.sidebarHeight + dims.containerTop; - var colliderTop = dims.viewportTop + dims.topSpacing; - var colliderBottom = dims.viewportBottom - dims.bottomSpacing; + if ('VIEWPORT-TOP' === this.affixedType) { + // Adjust translate Y in the case decrease top spacing value. + if (dims.topSpacing < dims.lastTopSpacing) { + dims.translateY += dims.lastTopSpacing - dims.topSpacing; + this._reStyle = true; + } + } else if ('VIEWPORT-BOTTOM' === this.affixedType) { + // Adjust translate Y in the case decrease bottom spacing value. + if (dims.bottomSpacing < dims.lastBottomSpacing) { + dims.translateY += dims.lastBottomSpacing - dims.bottomSpacing; + this._reStyle = true; + } + } - // When browser is scrolling top. - if ('up' === this.direction) { - if (colliderTop <= dims.containerTop) { + dims.lastTopSpacing = dims.topSpacing; + dims.lastBottomSpacing = dims.bottomSpacing; + } + }, { + key: 'isSidebarFitsViewport', + value: function isSidebarFitsViewport() { + return this.dimensions.sidebarHeight < this.dimensions.viewportHeight; + } + }, { + key: 'observeScrollDir', + value: function observeScrollDir() { + var dims = this.dimensions; + if (dims.lastViewportTop === dims.viewportTop) return; + + var furthest = 'down' === this.direction ? Math.min : Math.max; + + // If the browser is scrolling not in the same direction. + if (dims.viewportTop === furthest(dims.viewportTop, dims.lastViewportTop)) this.direction = 'down' === this.direction ? 'up' : 'down'; + } + }, { + key: 'getAffixType', + value: function getAffixType() { + this._calcDimensionsWithScroll(); + var dims = this.dimensions; + var colliderTop = dims.viewportTop + dims.topSpacing; + var affixType = this.affixedType; + + if (colliderTop <= dims.containerTop || dims.containerHeight <= dims.sidebarHeight) { dims.translateY = 0; affixType = 'STATIC'; - } else if (colliderTop <= dims.translateY + dims.containerTop) { - dims.translateY = colliderTop - dims.containerTop; - affixType = 'VIEWPORT-TOP'; - } else if (!this.isSidebarFitsViewport() && dims.containerTop <= colliderTop) { - affixType = 'VIEWPORT-UNBOTTOM'; + } else { + affixType = 'up' === this.direction ? this._getAffixTypeScrollingUp() : this._getAffixTypeScrollingDown(); } - // When browser is scrolling up. - } else { - // When sidebar element is not bigger than screen viewport. - if (this.isSidebarFitsViewport()) { + // Make sure the translate Y is not bigger than container height. + dims.translateY = Math.max(0, dims.translateY); + dims.translateY = Math.min(dims.containerHeight, dims.translateY); + dims.translateY = Math.round(dims.translateY); + + dims.lastViewportTop = dims.viewportTop; + return affixType; + } + }, { + key: '_getAffixTypeScrollingDown', + value: function _getAffixTypeScrollingDown() { + var dims = this.dimensions; + var sidebarBottom = dims.sidebarHeight + dims.containerTop; + var colliderTop = dims.viewportTop + dims.topSpacing; + var colliderBottom = dims.viewportBottom - dims.bottomSpacing; + var affixType = this.affixedType; + + if (this.isSidebarFitsViewport()) { if (dims.sidebarHeight + colliderTop >= dims.containerBottom) { dims.translateY = dims.containerBottom - sidebarBottom; affixType = 'CONTAINER-BOTTOM'; @@ -370,431 +378,371 @@ var StickySidebar = function () { dims.translateY = colliderTop - dims.containerTop; affixType = 'VIEWPORT-TOP'; } - // When sidebar element is bigger than screen viewport. } else { - if (dims.containerBottom <= colliderBottom) { dims.translateY = dims.containerBottom - sidebarBottom; affixType = 'CONTAINER-BOTTOM'; } else if (sidebarBottom + dims.translateY <= colliderBottom) { dims.translateY = colliderBottom - sidebarBottom; affixType = 'VIEWPORT-BOTTOM'; - } else if (dims.containerTop + dims.translateY <= colliderTop) { + } else if (dims.containerTop + dims.translateY <= colliderTop && 0 !== dims.translateY && dims.maxTranslateY !== dims.translateY) { affixType = 'VIEWPORT-UNBOTTOM'; } } + + return affixType; } + }, { + key: '_getAffixTypeScrollingUp', + value: function _getAffixTypeScrollingUp() { + var dims = this.dimensions; + var sidebarBottom = dims.sidebarHeight + dims.containerTop; + var colliderTop = dims.viewportTop + dims.topSpacing; + var colliderBottom = dims.viewportBottom - dims.bottomSpacing; + var affixType = this.affixedType; + + if (colliderTop <= dims.translateY + dims.containerTop) { + dims.translateY = colliderTop - dims.containerTop; + affixType = 'VIEWPORT-TOP'; + } else if (dims.containerBottom <= colliderBottom) { + dims.translateY = dims.containerBottom - sidebarBottom; + affixType = 'CONTAINER-BOTTOM'; + } else if (!this.isSidebarFitsViewport()) { - // Make sure the translate Y is not bigger than container height. - dims.translateY = Math.max(0, dims.translateY); - dims.translateY = Math.min(dims.containerHeight, dims.translateY); + if (dims.containerTop <= colliderTop && 0 !== dims.translateY && dims.maxTranslateY !== dims.translateY) { + affixType = 'VIEWPORT-UNBOTTOM'; + } + } - dims.lastViewportTop = dims.viewportTop; - return affixType; - } + return affixType; + } + }, { + key: '_getStyle', + value: function _getStyle(affixType) { + if ('undefined' === typeof affixType) return; + + var style = { inner: {}, outer: {} }; + var dims = this.dimensions; + + switch (affixType) { + case 'VIEWPORT-TOP': + style.inner = { position: 'fixed', top: dims.topSpacing, + left: dims.sidebarLeft - dims.viewportLeft, width: dims.sidebarWidth }; + break; + case 'VIEWPORT-BOTTOM': + style.inner = { position: 'fixed', top: 'auto', left: dims.sidebarLeft, + bottom: dims.bottomSpacing, width: dims.sidebarWidth }; + break; + case 'CONTAINER-BOTTOM': + case 'VIEWPORT-UNBOTTOM': + var translate = this._getTranslate(0, dims.translateY + 'px'); + + if (translate) style.inner = { transform: translate };else style.inner = { position: 'absolute', top: dims.translateY, width: dims.sidebarWidth }; + break; + } - /** - * Gets inline style of sticky sidebar wrapper and inner wrapper according - * to its affix type. - * @private - * @param {String} affixType - Affix type of sticky sidebar. - * @return {Object} - */ + switch (affixType) { + case 'VIEWPORT-TOP': + case 'VIEWPORT-BOTTOM': + case 'VIEWPORT-UNBOTTOM': + case 'CONTAINER-BOTTOM': + style.outer = { height: dims.sidebarHeight, position: 'relative' }; + break; + } - }, { - key: '_getStyle', - value: function _getStyle(affixType) { - if ('undefined' === typeof affixType) return; - - var style = { inner: {}, outer: {} }; - var dims = this.dimensions; - - switch (affixType) { - case 'VIEWPORT-TOP': - style.inner = { position: 'fixed', top: dims.topSpacing, - left: dims.sidebarLeft - dims.viewportLeft, width: dims.sidebarWidth }; - break; - case 'VIEWPORT-BOTTOM': - style.inner = { position: 'fixed', top: 'auto', left: dims.sidebarLeft, - bottom: dims.bottomSpacing, width: dims.sidebarWidth }; - break; - case 'CONTAINER-BOTTOM': - case 'VIEWPORT-UNBOTTOM': - var translate = this._getTranslate(0, dims.translateY + 'px'); - - if (translate) style.inner = { transform: translate };else style.inner = { position: 'absolute', top: dims.translateY, width: dims.sidebarWidth }; - break; - } + style.outer = StickySidebar.extend({ height: '', position: '' }, style.outer); + style.inner = StickySidebar.extend({ position: 'relative', top: '', left: '', + bottom: '', width: '', transform: '' }, style.inner); - switch (affixType) { - case 'VIEWPORT-TOP': - case 'VIEWPORT-BOTTOM': - case 'VIEWPORT-UNBOTTOM': - case 'CONTAINER-BOTTOM': - style.outer = { height: dims.sidebarHeight, position: 'relative' }; - break; + return style; } + }, { + key: 'stickyPosition', + value: function stickyPosition(force) { + if (this._breakpoint) return; - style.outer = StickySidebar.extend({ height: '', position: '' }, style.outer); - style.inner = StickySidebar.extend({ position: 'relative', top: '', left: '', - bottom: '', width: '', transform: this._getTranslate() }, style.inner); + force = this._reStyle || force || false; - return style; - } + var affixType = this.getAffixType(); + var style = this._getStyle(affixType); - /** - * Cause the sidebar to be sticky according to affix type by adding inline - * style, adding helper class and trigger events. - * @function - * @protected - * @param {string} force - Update sticky sidebar position by force. - */ + if ((this.affixedType != affixType || force) && affixType) { + var affixEvent = 'affix.' + affixType.toLowerCase().replace('viewport-', '') + EVENT_KEY; + StickySidebar.eventTrigger(this.sidebar, affixEvent); - }, { - key: 'stickyPosition', - value: function stickyPosition(force) { - if (this._breakpoint) return; + if ('STATIC' === affixType) StickySidebar.removeClass(this.sidebar, this.options.stickyClass);else StickySidebar.addClass(this.sidebar, this.options.stickyClass); - force = this._reStyle || force || false; + for (var key in style.outer) { + var unit = 'number' === typeof style.outer[key] ? 'px' : ''; + this.sidebar.style[key] = style.outer[key] + unit; + } - var affixType = this.getAffixType(); - var style = this._getStyle(affixType); + for (var _key in style.inner) { + var _unit = 'number' === typeof style.inner[_key] ? 'px' : ''; + this.sidebarInner.style[_key] = style.inner[_key] + _unit; + } - if ((this.affixedType != affixType || force) && affixType) { - var affixEvent = 'affix.' + affixType.toLowerCase().replace('viewport-', '') + EVENT_KEY; - StickySidebar.eventTrigger(this.sidebar, affixEvent); + var affixedEvent = 'affixed.' + affixType.toLowerCase().replace('viewport-', '') + EVENT_KEY; + StickySidebar.eventTrigger(this.sidebar, affixedEvent); + } else { + if (this._initialized) this.sidebarInner.style.left = style.inner.left; + } - if ('STATIC' === affixType) StickySidebar.removeClass(this.sidebar, this.options.stickyClass);else StickySidebar.addClass(this.sidebar, this.options.stickyClass); + this.affixedType = affixType; + } + }, { + key: '_widthBreakpoint', + value: function _widthBreakpoint() { - for (var key in style.outer) { - this.sidebar.style[key] = style.outer[key]; - } + if (window.innerWidth <= this.options.minWidth) { + this._breakpoint = true; + this.affixedType = 'STATIC'; - for (var _key in style.inner) { - var _unit2 = 'number' === typeof style.inner[_key] ? 'px' : ''; - this.sidebarInner.style[_key] = style.inner[_key] + _unit2; + this.sidebar.removeAttribute('style'); + StickySidebar.removeClass(this.sidebar, this.options.stickyClass); + this.sidebarInner.removeAttribute('style'); + } else { + this._breakpoint = false; } + } + }, { + key: 'updateSticky', + value: function updateSticky() { + var _this3 = this; + + var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + if (this._running) return; + this._running = true; + + (function (eventType) { + requestAnimationFrame(function () { + switch (eventType) { + // When browser is scrolling and re-calculate just dimensions + // within scroll. + case 'scroll': + _this3._calcDimensionsWithScroll(); + _this3.observeScrollDir(); + _this3.stickyPosition(); + break; + + // When browser is resizing or there's no event, observe width + // breakpoint and re-calculate dimensions. + case 'resize': + default: + _this3._widthBreakpoint(); + _this3.calcDimensions(); + _this3.stickyPosition(true); + break; + } + _this3._running = false; + }); + })(event.type); + } + }, { + key: '_setSupportFeatures', + value: function _setSupportFeatures() { + var support = this.support; - var affixedEvent = 'affixed.' + affixType.toLowerCase().replace('viewport-', '') + EVENT_KEY; - StickySidebar.eventTrigger(this.sidebar, affixedEvent); - } else { - if (this._initialized) this.sidebarInner.style.left = style.inner.left; + support.transform = StickySidebar.supportTransform(); + support.transform3d = StickySidebar.supportTransform(true); } + }, { + key: '_getTranslate', + value: function _getTranslate() { + var y = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var z = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + + if (this.support.transform3d) return 'translate3d(' + y + ', ' + x + ', ' + z + ')';else if (this.support.translate) return 'translate(' + y + ', ' + x + ')';else return false; + } + }, { + key: 'destroy', + value: function destroy() { + window.removeEventListener('resize', this, { capture: false }); + window.removeEventListener('scroll', this, { capture: false }); - this.affixedType = affixType; - } + this.sidebar.classList.remove(this.options.stickyClass); + this.sidebar.style.minHeight = ''; - /** - * Breakdown sticky sidebar when window width is below `options.minWidth` value. - * @protected - */ + this.sidebar.removeEventListener('update' + EVENT_KEY, this); - }, { - key: '_widthBreakpoint', - value: function _widthBreakpoint() { + var styleReset = { inner: {}, outer: {} }; - if (window.innerWidth <= this.options.minWidth) { - this._breakpoint = true; - this.affixedType = 'STATIC'; + styleReset.inner = { position: '', top: '', left: '', bottom: '', width: '', transform: '' }; + styleReset.outer = { height: '', position: '' }; - this.sidebar.removeAttribute('style'); - StickySidebar.removeClass(this.sidebar, this.options.stickyClass); - this.sidebarInner.removeAttribute('style'); - } else { - this._breakpoint = false; + for (var key in styleReset.outer) { + this.sidebar.style[key] = styleReset.outer[key]; + }for (var _key2 in styleReset.inner) { + this.sidebarInner.style[_key2] = styleReset.inner[_key2]; + }if (this.options.resizeSensor && 'undefined' !== typeof ResizeSensor) { + ResizeSensor.detach(this.sidebarInner, this.handleEvent); + ResizeSensor.detach(this.container, this.handleEvent); + } } - } - - /** - * Switches between functions stack for each event type, if there's no - * event, it will re-initialize sticky sidebar. - * @public - */ - - }, { - key: 'updateSticky', - value: function updateSticky() { - var _this3 = this; - - var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - - if (this._running) return; - this._running = true; - - (function (eventType) { - - requestAnimationFrame(function () { - switch (eventType) { - // When browser is scrolling and re-calculate just dimensions - // within scroll. - case 'scroll': - _this3._calcDimensionsWithScroll(); - _this3.observeScrollDir(); - _this3.stickyPosition(); - break; - - // When browser is resizing or there's no event, observe width - // breakpoint and re-calculate dimensions. - case 'resize': - default: - _this3._widthBreakpoint(); - _this3.calcDimensions(); - _this3.stickyPosition(true); - break; + }], [{ + key: 'supportTransform', + value: function supportTransform(transform3d) { + var result = false, + property = transform3d ? 'perspective' : 'transform', + upper = property.charAt(0).toUpperCase() + property.slice(1), + prefixes = ['Webkit', 'Moz', 'O', 'ms'], + support = document.createElement('support'), + style = support.style; + + (property + ' ' + prefixes.join(upper + ' ') + upper).split(' ').forEach(function (property, i) { + if (style[property] !== undefined) { + result = property; + return false; } - _this3._running = false; }); - })(event.type); - } - - /** - * Set browser support features to the public property. - * @private - */ - - }, { - key: '_setSupportFeatures', - value: function _setSupportFeatures() { - var support = this.support; - - support.transform = StickySidebar.supportTransform(); - support.transform3d = StickySidebar.supportTransform(true); - } - - /** - * Get translate value, if the browser supports transfrom3d, it will adopt it. - * and the same with translate. if browser doesn't support both return false. - * @param {Number} y - Value of Y-axis. - * @param {Number} x - Value of X-axis. - * @param {Number} z - Value of Z-axis. - * @return {String|False} - */ - - }, { - key: '_getTranslate', - value: function _getTranslate() { - var y = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - var x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - var z = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; - - if (this.support.transform3d) return 'translate3d(' + y + ', ' + x + ', ' + z + ')';else if (this.support.translate) return 'translate(' + y + ', ' + x + ')';else return false; - } - - /** - * Destroy sticky sidebar plugin. - * @public - */ - - }, { - key: 'destroy', - value: function destroy() { - window.removeEventListener('resize', this, { caption: false }); - window.removeEventListener('scroll', this, { caption: false }); - - this.sidebar.classList.remove(this.options.stickyClass); - this.sidebar.style.minHeight = ''; + return result; + } + }, { + key: 'eventTrigger', + value: function eventTrigger(element, eventName, data) { + try { + var event = new CustomEvent(eventName, { detail: data }); + } catch (e) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent(eventName, true, true, data); + } + element.dispatchEvent(event); + } + }, { + key: 'extend', + value: function extend(defaults, options) { + var results = {}; + for (var key in defaults) { + if ('undefined' !== typeof options[key]) results[key] = options[key];else results[key] = defaults[key]; + } + return results; + } + }, { + key: 'offsetRelative', + value: function offsetRelative(element) { + var result = { left: 0, top: 0 }; - this.sidebar.removeEventListener('update' + EVENT_KEY, this); + do { + var offsetTop = element.offsetTop; + var offsetLeft = element.offsetLeft; - var styleReset = { inner: {}, outer: {} }; + if (!isNaN(offsetTop)) result.top += offsetTop; - styleReset.inner = { position: '', top: '', left: '', bottom: '', width: '', transform: '' }; - styleReset.outer = { height: '', position: '' }; + if (!isNaN(offsetLeft)) result.left += offsetLeft; - for (var key in styleReset.outer) { - this.sidebar.style[key] = styleReset.outer[key]; - }for (var _key2 in styleReset.inner) { - this.sidebarInner.style[_key2] = styleReset.inner[_key2]; - }if (this.options.resizeSensor && 'undefined' !== typeof ResizeSensor) { - ResizeSensor.detach(this.sidebarInner, this.handleEvent); - ResizeSensor.detach(this.container, this.handleEvent); + element = 'BODY' === element.tagName ? element.parentElement : element.offsetParent; + } while (element); + return result; } - } - - /** - * Determine if the browser supports CSS transform feature. - * @function - * @static - * @param {Boolean} transform3d - Detect transform with translate3d. - * @return {String} - */ - - }], [{ - key: 'supportTransform', - value: function supportTransform(transform3d) { - var result = false, - property = transform3d ? 'perspective' : 'transform', - upper = property.charAt(0).toUpperCase() + property.slice(1), - prefixes = ['Webkit', 'Moz', 'O', 'ms'], - support = document.createElement('support'), - style = support.style; - - (property + ' ' + prefixes.join(upper + ' ') + upper).split(' ').forEach(function (property, i) { - if (style[property] !== undefined) { - result = property; - return false; + }, { + key: 'addClass', + value: function addClass(element, className) { + if (!StickySidebar.hasClass(element, className)) { + if (element.classList) element.classList.add(className);else element.className += ' ' + className; } - }); - return result; - } - - /** - * Trigger custom event. - * @static - * @param {DOMObject} element - Target element on the DOM. - * @param {String} eventName - Event name. - * @param {Object} data - - */ - - }, { - key: 'eventTrigger', - value: function eventTrigger(element, eventName, data) { - try { - var event = new CustomEvent(eventName, { detail: data }); - } catch (e) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent(eventName, true, true, data); } - element.dispatchEvent(event); - } - - /** - * Extend options object with defaults. - * @function - * @static - */ - - }, { - key: 'extend', - value: function extend(defaults, options) { - var results = {}; - for (var key in defaults) { - if ('undefined' !== typeof options[key]) results[key] = options[key];else results[key] = defaults[key]; + }, { + key: 'removeClass', + value: function removeClass(element, className) { + if (StickySidebar.hasClass(element, className)) { + if (element.classList) element.classList.remove(className);else element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); + } } - return results; - } - - /** - * Get current coordinates left and top of specific element. - * @static - */ - - }, { - key: 'offsetRelative', - value: function offsetRelative(element) { - var result = { left: 0, top: 0 }; - - do { - var offsetTop = element.offsetTop; - var offsetLeft = element.offsetLeft; + }, { + key: 'hasClass', + value: function hasClass(element, className) { + if (element.classList) return element.classList.contains(className);else return new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className); + } + }, { + key: 'defaults', + get: function () { + return DEFAULTS; + } + }]); - if (!isNaN(offsetTop)) result.top += offsetTop; + return StickySidebar; + }(); - if (!isNaN(offsetLeft)) result.left += offsetLeft; + return StickySidebar; + }(); - element = 'BODY' === element.tagName ? element.parentElement : element.offsetParent; - } while (element); - return result; - } + exports.default = StickySidebar; - /** - * Add specific class name to specific element. - * @static - * @param {ObjectDOM} element - * @param {String} className - */ - }, { - key: 'addClass', - value: function addClass(element, className) { - if (!StickySidebar.hasClass(element, className)) { - if (element.classList) element.classList.add(className);else element.className += ' ' + className; - } - } + // Global + // ------------------------- + window.StickySidebar = StickySidebar; +}); +}); - /** - * Remove specific class name to specific element - * @static - * @param {ObjectDOM} element - * @param {String} className - */ +unwrapExports(stickySidebar); - }, { - key: 'removeClass', - value: function removeClass(element, className) { - if (StickySidebar.hasClass(element, className)) { - if (element.classList) element.classList.remove(className);else element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); - } - } +var jquery_stickySidebar = createCommonjsModule(function (module, exports) { +(function (global, factory) { + if (typeof undefined === "function" && undefined.amd) { + undefined(['./sticky-sidebar'], factory); + } else { + factory(stickySidebar); + } +})(commonjsGlobal, function (_stickySidebar) { + 'use strict'; - /** - * Determine weather the element has specific class name. - * @static - * @param {ObjectDOM} element - * @param {String} className - */ + var _stickySidebar2 = _interopRequireDefault(_stickySidebar); - }, { - key: 'hasClass', - value: function hasClass(element, className) { - if (element.classList) return element.classList.contains(className);else return new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className); - } - }]); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + default: obj + }; + } - return StickySidebar; - }(); + (function () { + if ('undefined' === typeof window) return; - return StickySidebar; -}(); + var plugin = window.$ || window.jQuery || window.Zepto; + var DATA_NAMESPACE = 'stickySidebar'; -// Global -// ------------------------- -window.StickySidebar = StickySidebar; + // Make sure the site has jquery or zepto plugin. + if (plugin) { + var _jQueryPlugin = function (config) { + return this.each(function () { + var $this = plugin(this), + data = plugin(this).data(DATA_NAMESPACE); -(function () { - if ('undefined' === typeof window) return; + if (!data) { + data = new _stickySidebar2.default(this, typeof config == 'object' && config); + $this.data(DATA_NAMESPACE, data); + } - var plugin = window.$ || window.jQuery || window.Zepto; - var DATA_NAMESPACE = 'stickySidebar'; + if ('string' === typeof config) { + if (data[config] === undefined && ['destroy', 'updateSticky'].indexOf(config) === -1) throw new Error('No method named "' + config + '"'); - // Make sure the site has jquery or zepto plugin. - if (plugin) { - /** - * Sticky Sidebar Plugin Defintion. - * @param {Object|String} - config - */ - var _jQueryPlugin = function (config) { - return this.each(function () { - var $this = plugin(this), - data = plugin(this).data(DATA_NAMESPACE); - - if (!data) { - data = new StickySidebar(this, typeof config == 'object' && config); - $this.data(DATA_NAMESPACE, data); - } + data[config](); + } + }); + }; - if ('string' === typeof config) { - if (data[config] === undefined && ['destroy', 'updateSticky'].indexOf(config) === -1) throw new Error('No method named "' + config + '"'); + plugin.fn.stickySidebar = _jQueryPlugin; + plugin.fn.stickySidebar.Constructor = _stickySidebar2.default; - data[config](); - } - }); - }; + var old = plugin.fn.stickySidebar; - plugin.fn.stickySidebar = _jQueryPlugin; - plugin.fn.stickySidebar.Constructor = StickySidebar; + /** + * Sticky Sidebar No Conflict. + */ + plugin.fn.stickySidebar.noConflict = function () { + plugin.fn.stickySidebar = old; + return this; + }; + } + })(); +}); +}); - var old = plugin.fn.stickySidebar; +var jquery_stickySidebar$1 = unwrapExports(jquery_stickySidebar); - /** - * Sticky Sidebar No Conflict. - */ - plugin.fn.stickySidebar.noConflict = function () { - plugin.fn.stickySidebar = old; - return this; - }; - } -})(); +return jquery_stickySidebar$1; }))); diff --git a/dist/jquery.sticky-sidebar.js.map b/dist/jquery.sticky-sidebar.js.map index 3598381..80a10e7 100644 --- a/dist/jquery.sticky-sidebar.js.map +++ b/dist/jquery.sticky-sidebar.js.map @@ -1 +1 @@ -{"version":3,"file":"jquery.sticky-sidebar.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file +{"version":3,"file":"jquery.sticky-sidebar.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/dist/jquery.sticky-sidebar.min.js b/dist/jquery.sticky-sidebar.min.js index fd8d83c..a0e0c2b 100644 --- a/dist/jquery.sticky-sidebar.min.js +++ b/dist/jquery.sticky-sidebar.min.js @@ -5,4 +5,4 @@ * @author Ahmed Bouhuolia * @license The MIT License (MIT) **/ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e():"function"==typeof define&&define.amd?define(e):e()}(0,function(){"use strict";var t=function(){function t(t,e){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{};if(function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,n),this.options=n.extend(i,s),this.sidebar="string"==typeof t?document.querySelector(t):t,void 0===this.sidebar)throw new Error("There is no specific sidebar element.");this.sidebarInner=!1,this.container=this.sidebar.parentElement,this.affixedType="STATIC",this.direction="down",this.support={transform:!1,transform3d:!1},this._initialized=!1,this._reStyle=!1,this._breakpoint=!1,this._resizeListeners=[],this.dimensions={translateY:0,topSpacing:0,lastTopSpacing:0,bottomSpacing:0,lastBottomSpacing:0,sidebarHeight:0,sidebarWidth:0,containerTop:0,containerHeight:0,viewportHeight:0,viewportTop:0,lastViewportTop:0},["handleEvent"].forEach(function(t){e[t]=e[t].bind(e)}),this.initialize()}return t(n,[{key:"initialize",value:function(){var t=this;if(this._setSupportFeatures(),this.options.innerWrapperSelector&&(this.sidebarInner=this.sidebar.querySelector(this.options.innerWrapperSelector),null===this.sidebarInner&&(this.sidebarInner=!1)),!this.sidebarInner){var e=document.createElement("div");for(e.setAttribute("class","inner-wrapper-sticky"),this.sidebar.appendChild(e);this.sidebar.firstChild!=e;)e.appendChild(this.sidebar.firstChild);this.sidebarInner=this.sidebar.querySelector(".inner-wrapper-sticky")}if(this.options.containerSelector){var i=document.querySelectorAll(this.options.containerSelector);if((i=Array.prototype.slice.call(i)).forEach(function(e,i){e.contains(t.sidebar)&&(t.container=e)}),!i.length)throw new Error("The container does not contains on the sidebar.")}"function"!=typeof this.options.topSpacing&&(this.options.topSpacing=parseInt(this.options.topSpacing)||0),"function"!=typeof this.options.bottomSpacing&&(this.options.bottomSpacing=parseInt(this.options.bottomSpacing)||0),this._widthBreakpoint(),this.calcDimensions(),this.stickyPosition(),this.bindEvents(),this._initialized=!0}},{key:"bindEvents",value:function(){window.addEventListener("resize",this,{passive:!0,capture:!1}),window.addEventListener("scroll",this,{passive:!0,capture:!1}),this.sidebar.addEventListener("update"+e,this),this.options.resizeSensor&&"undefined"!=typeof ResizeSensor&&(new ResizeSensor(this.sidebarInner,this.handleEvent),new ResizeSensor(this.container,this.handleEvent))}},{key:"handleEvent",value:function(t){this.updateSticky(t)}},{key:"calcDimensions",value:function(){if(!this._breakpoint){var t=this.dimensions;t.containerTop=n.offsetRelative(this.container).top,t.containerHeight=this.container.clientHeight,t.containerBottom=t.containerTop+t.containerHeight,t.sidebarHeight=this.sidebarInner.offsetHeight,t.sidebarWidth=this.sidebarInner.offsetWidth,t.viewportHeight=window.innerHeight,this._calcDimensionsWithScroll()}}},{key:"_calcDimensionsWithScroll",value:function(){var t=this.dimensions;t.sidebarLeft=n.offsetRelative(this.sidebar).left,t.viewportTop=document.documentElement.scrollTop||document.body.scrollTop,t.viewportBottom=t.viewportTop+t.viewportHeight,t.viewportLeft=document.documentElement.scrollLeft||document.body.scrollLeft,t.topSpacing=this.options.topSpacing,t.bottomSpacing=this.options.bottomSpacing,"function"==typeof t.topSpacing&&(t.topSpacing=parseInt(t.topSpacing(this.sidebar))||0),"function"==typeof t.bottomSpacing&&(t.bottomSpacing=parseInt(t.bottomSpacing(this.sidebar))||0),"VIEWPORT-TOP"===this.affixedType?t.topSpacing=t.containerBottom?(t.translateY=t.containerBottom-i,e="CONTAINER-BOTTOM"):n>=t.containerTop&&(t.translateY=n-t.containerTop,e="VIEWPORT-TOP"):t.containerBottom<=s?(t.translateY=t.containerBottom-i,e="CONTAINER-BOTTOM"):i+t.translateY<=s?(t.translateY=s-i,e="VIEWPORT-BOTTOM"):t.containerTop+t.translateY<=n&&(e="VIEWPORT-UNBOTTOM"),t.translateY=Math.max(0,t.translateY),t.translateY=Math.min(t.containerHeight,t.translateY),t.lastViewportTop=t.viewportTop,e}},{key:"_getStyle",value:function(t){if(void 0!==t){var e={inner:{},outer:{}},i=this.dimensions;switch(t){case"VIEWPORT-TOP":e.inner={position:"fixed",top:i.topSpacing,left:i.sidebarLeft-i.viewportLeft,width:i.sidebarWidth};break;case"VIEWPORT-BOTTOM":e.inner={position:"fixed",top:"auto",left:i.sidebarLeft,bottom:i.bottomSpacing,width:i.sidebarWidth};break;case"CONTAINER-BOTTOM":case"VIEWPORT-UNBOTTOM":var s=this._getTranslate(0,i.translateY+"px");e.inner=s?{transform:s}:{position:"absolute",top:i.translateY,width:i.sidebarWidth}}switch(t){case"VIEWPORT-TOP":case"VIEWPORT-BOTTOM":case"VIEWPORT-UNBOTTOM":case"CONTAINER-BOTTOM":e.outer={height:i.sidebarHeight,position:"relative"}}return e.outer=n.extend({height:"",position:""},e.outer),e.inner=n.extend({position:"relative",top:"",left:"",bottom:"",width:"",transform:this._getTranslate()},e.inner),e}}},{key:"stickyPosition",value:function(t){if(!this._breakpoint){t=this._reStyle||t||!1;var i=this.getAffixType(),s=this._getStyle(i);if((this.affixedType!=i||t)&&i){var o="affix."+i.toLowerCase().replace("viewport-","")+e;n.eventTrigger(this.sidebar,o),"STATIC"===i?n.removeClass(this.sidebar,this.options.stickyClass):n.addClass(this.sidebar,this.options.stickyClass);for(var r in s.outer)this.sidebar.style[r]=s.outer[r];for(var a in s.inner){var c="number"==typeof s.inner[a]?"px":"";this.sidebarInner.style[a]=s.inner[a]+c}var p="affixed."+i.toLowerCase().replace("viewport-","")+e;n.eventTrigger(this.sidebar,p)}else this._initialized&&(this.sidebarInner.style.left=s.inner.left);this.affixedType=i}}},{key:"_widthBreakpoint",value:function(){window.innerWidth<=this.options.minWidth?(this._breakpoint=!0,this.affixedType="STATIC",this.sidebar.removeAttribute("style"),n.removeClass(this.sidebar,this.options.stickyClass),this.sidebarInner.removeAttribute("style")):this._breakpoint=!1}},{key:"updateSticky",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this._running||(this._running=!0,function(e){requestAnimationFrame(function(){switch(e){case"scroll":t._calcDimensionsWithScroll(),t.observeScrollDir(),t.stickyPosition();break;case"resize":default:t._widthBreakpoint(),t.calcDimensions(),t.stickyPosition(!0)}t._running=!1})}(e.type))}},{key:"_setSupportFeatures",value:function(){var t=this.support;t.transform=n.supportTransform(),t.transform3d=n.supportTransform(!0)}},{key:"_getTranslate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return this.support.transform3d?"translate3d("+t+", "+e+", "+i+")":!!this.support.translate&&"translate("+t+", "+e+")"}},{key:"destroy",value:function(){window.removeEventListener("resize",this,{caption:!1}),window.removeEventListener("scroll",this,{caption:!1}),this.sidebar.classList.remove(this.options.stickyClass),this.sidebar.style.minHeight="",this.sidebar.removeEventListener("update"+e,this);var t={inner:{},outer:{}};t.inner={position:"",top:"",left:"",bottom:"",width:"",transform:""},t.outer={height:"",position:""};for(var i in t.outer)this.sidebar.style[i]=t.outer[i];for(var n in t.inner)this.sidebarInner.style[n]=t.inner[n];this.options.resizeSensor&&"undefined"!=typeof ResizeSensor&&(ResizeSensor.detach(this.sidebarInner,this.handleEvent),ResizeSensor.detach(this.container,this.handleEvent))}}],[{key:"supportTransform",value:function(t){var e=!1,i=t?"perspective":"transform",n=i.charAt(0).toUpperCase()+i.slice(1),s=document.createElement("support").style;return(i+" "+["Webkit","Moz","O","ms"].join(n+" ")+n).split(" ").forEach(function(t,i){if(void 0!==s[t])return e=t,!1}),e}},{key:"eventTrigger",value:function(t,e,i){try{n=new CustomEvent(e,{detail:i})}catch(t){var n;(n=document.createEvent("CustomEvent")).initCustomEvent(e,!0,!0,i)}t.dispatchEvent(n)}},{key:"extend",value:function(t,e){var i={};for(var n in t)void 0!==e[n]?i[n]=e[n]:i[n]=t[n];return i}},{key:"offsetRelative",value:function(t){var e={left:0,top:0};do{var i=t.offsetTop,n=t.offsetLeft;isNaN(i)||(e.top+=i),isNaN(n)||(e.left+=n),t="BODY"===t.tagName?t.parentElement:t.offsetParent}while(t);return e}},{key:"addClass",value:function(t,e){n.hasClass(t,e)||(t.classList?t.classList.add(e):t.className+=" "+e)}},{key:"removeClass",value:function(t,e){n.hasClass(t,e)&&(t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\b)"+e.split(" ").join("|")+"(\\b|$)","gi")," "))}},{key:"hasClass",value:function(t,e){return t.classList?t.classList.contains(e):new RegExp("(^| )"+e+"( |$)","gi").test(t.className)}}]),n}()}();window.StickySidebar=e,function(){if("undefined"!=typeof window){var t=window.$||window.jQuery||window.Zepto,i="stickySidebar";if(t){t.fn.stickySidebar=function(n){return this.each(function(){var s=t(this),o=t(this).data(i);if(o||(o=new e(this,"object"==typeof n&&n),s.data(i,o)),"string"==typeof n){if(void 0===o[n]&&-1===["destroy","updateSticky"].indexOf(n))throw new Error('No method named "'+n+'"');o[n]()}})},t.fn.stickySidebar.Constructor=e;var n=t.fn.stickySidebar;t.fn.stickySidebar.noConflict=function(){return t.fn.stickySidebar=n,this}}}}()}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.StickySidebar=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule?t.default:t}function e(t,e){return e={exports:{}},t(e,e.exports),e.exports}"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var i=e(function(t,e){!function(t,i){i(e)}(0,function(t){function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function t(t,e){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{};if(e(this,o),this.options=o.extend(n,s),this.sidebar="string"==typeof t?document.querySelector(t):t,void 0===this.sidebar)throw new Error("There is no specific sidebar element.");this.sidebarInner=!1,this.container=this.sidebar.parentElement,this.affixedType="STATIC",this.direction="down",this.support={transform:!1,transform3d:!1},this._initialized=!1,this._reStyle=!1,this._breakpoint=!1,this.dimensions={translateY:0,maxTranslateY:0,topSpacing:0,lastTopSpacing:0,bottomSpacing:0,lastBottomSpacing:0,sidebarHeight:0,sidebarWidth:0,containerTop:0,containerHeight:0,viewportHeight:0,viewportTop:0,lastViewportTop:0},["handleEvent"].forEach(function(t){i[t]=i[t].bind(i)}),this.initialize()}return i(o,[{key:"initialize",value:function(){var t=this;if(this._setSupportFeatures(),this.options.innerWrapperSelector&&(this.sidebarInner=this.sidebar.querySelector(this.options.innerWrapperSelector),null===this.sidebarInner&&(this.sidebarInner=!1)),!this.sidebarInner){var e=document.createElement("div");for(e.setAttribute("class","inner-wrapper-sticky"),this.sidebar.appendChild(e);this.sidebar.firstChild!=e;)e.appendChild(this.sidebar.firstChild);this.sidebarInner=this.sidebar.querySelector(".inner-wrapper-sticky")}if(this.options.containerSelector){var i=document.querySelectorAll(this.options.containerSelector);if((i=Array.prototype.slice.call(i)).forEach(function(e,i){e.contains(t.sidebar)&&(t.container=e)}),!i.length)throw new Error("The container does not contains on the sidebar.")}"function"!=typeof this.options.topSpacing&&(this.options.topSpacing=parseInt(this.options.topSpacing)||0),"function"!=typeof this.options.bottomSpacing&&(this.options.bottomSpacing=parseInt(this.options.bottomSpacing)||0),this._widthBreakpoint(),this.calcDimensions(),this.stickyPosition(),this.bindEvents(),this._initialized=!0}},{key:"bindEvents",value:function(){window.addEventListener("resize",this,{passive:!0,capture:!1}),window.addEventListener("scroll",this,{passive:!0,capture:!1}),this.sidebar.addEventListener("update"+t,this),this.options.resizeSensor&&"undefined"!=typeof ResizeSensor&&(new ResizeSensor(this.sidebarInner,this.handleEvent),new ResizeSensor(this.container,this.handleEvent))}},{key:"handleEvent",value:function(t){this.updateSticky(t)}},{key:"calcDimensions",value:function(){if(!this._breakpoint){var t=this.dimensions;t.containerTop=o.offsetRelative(this.container).top,t.containerHeight=this.container.clientHeight,t.containerBottom=t.containerTop+t.containerHeight,t.sidebarHeight=this.sidebarInner.offsetHeight,t.sidebarWidth=this.sidebarInner.offsetWidth,t.viewportHeight=window.innerHeight,t.maxTranslateY=t.containerHeight-t.sidebarHeight,this._calcDimensionsWithScroll()}}},{key:"_calcDimensionsWithScroll",value:function(){var t=this.dimensions;t.sidebarLeft=o.offsetRelative(this.sidebar).left,t.viewportTop=document.documentElement.scrollTop||document.body.scrollTop,t.viewportBottom=t.viewportTop+t.viewportHeight,t.viewportLeft=document.documentElement.scrollLeft||document.body.scrollLeft,t.topSpacing=this.options.topSpacing,t.bottomSpacing=this.options.bottomSpacing,"function"==typeof t.topSpacing&&(t.topSpacing=parseInt(t.topSpacing(this.sidebar))||0),"function"==typeof t.bottomSpacing&&(t.bottomSpacing=parseInt(t.bottomSpacing(this.sidebar))||0),"VIEWPORT-TOP"===this.affixedType?t.topSpacing=t.containerBottom?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):i>=t.containerTop&&(t.translateY=i-t.containerTop,o="VIEWPORT-TOP"):t.containerBottom<=n?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):e+t.translateY<=n?(t.translateY=n-e,o="VIEWPORT-BOTTOM"):t.containerTop+t.translateY<=i&&0!==t.translateY&&t.maxTranslateY!==t.translateY&&(o="VIEWPORT-UNBOTTOM"),o}},{key:"_getAffixTypeScrollingUp",value:function(){var t=this.dimensions,e=t.sidebarHeight+t.containerTop,i=t.viewportTop+t.topSpacing,n=t.viewportBottom-t.bottomSpacing,o=this.affixedType;return i<=t.translateY+t.containerTop?(t.translateY=i-t.containerTop,o="VIEWPORT-TOP"):t.containerBottom<=n?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):this.isSidebarFitsViewport()||t.containerTop<=i&&0!==t.translateY&&t.maxTranslateY!==t.translateY&&(o="VIEWPORT-UNBOTTOM"),o}},{key:"_getStyle",value:function(t){if(void 0!==t){var e={inner:{},outer:{}},i=this.dimensions;switch(t){case"VIEWPORT-TOP":e.inner={position:"fixed",top:i.topSpacing,left:i.sidebarLeft-i.viewportLeft,width:i.sidebarWidth};break;case"VIEWPORT-BOTTOM":e.inner={position:"fixed",top:"auto",left:i.sidebarLeft,bottom:i.bottomSpacing,width:i.sidebarWidth};break;case"CONTAINER-BOTTOM":case"VIEWPORT-UNBOTTOM":var n=this._getTranslate(0,i.translateY+"px");e.inner=n?{transform:n}:{position:"absolute",top:i.translateY,width:i.sidebarWidth}}switch(t){case"VIEWPORT-TOP":case"VIEWPORT-BOTTOM":case"VIEWPORT-UNBOTTOM":case"CONTAINER-BOTTOM":e.outer={height:i.sidebarHeight,position:"relative"}}return e.outer=o.extend({height:"",position:""},e.outer),e.inner=o.extend({position:"relative",top:"",left:"",bottom:"",width:"",transform:""},e.inner),e}}},{key:"stickyPosition",value:function(e){if(!this._breakpoint){e=this._reStyle||e||!1;var i=this.getAffixType(),n=this._getStyle(i);if((this.affixedType!=i||e)&&i){var s="affix."+i.toLowerCase().replace("viewport-","")+t;o.eventTrigger(this.sidebar,s),"STATIC"===i?o.removeClass(this.sidebar,this.options.stickyClass):o.addClass(this.sidebar,this.options.stickyClass);for(var r in n.outer){var a="number"==typeof n.outer[r]?"px":"";this.sidebar.style[r]=n.outer[r]+a}for(var p in n.inner){var c="number"==typeof n.inner[p]?"px":"";this.sidebarInner.style[p]=n.inner[p]+c}var l="affixed."+i.toLowerCase().replace("viewport-","")+t;o.eventTrigger(this.sidebar,l)}else this._initialized&&(this.sidebarInner.style.left=n.inner.left);this.affixedType=i}}},{key:"_widthBreakpoint",value:function(){window.innerWidth<=this.options.minWidth?(this._breakpoint=!0,this.affixedType="STATIC",this.sidebar.removeAttribute("style"),o.removeClass(this.sidebar,this.options.stickyClass),this.sidebarInner.removeAttribute("style")):this._breakpoint=!1}},{key:"updateSticky",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this._running||(this._running=!0,function(e){requestAnimationFrame(function(){switch(e){case"scroll":t._calcDimensionsWithScroll(),t.observeScrollDir(),t.stickyPosition();break;case"resize":default:t._widthBreakpoint(),t.calcDimensions(),t.stickyPosition(!0)}t._running=!1})}(e.type))}},{key:"_setSupportFeatures",value:function(){var t=this.support;t.transform=o.supportTransform(),t.transform3d=o.supportTransform(!0)}},{key:"_getTranslate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return this.support.transform3d?"translate3d("+t+", "+e+", "+i+")":!!this.support.translate&&"translate("+t+", "+e+")"}},{key:"destroy",value:function(){window.removeEventListener("resize",this,{capture:!1}),window.removeEventListener("scroll",this,{capture:!1}),this.sidebar.classList.remove(this.options.stickyClass),this.sidebar.style.minHeight="",this.sidebar.removeEventListener("update"+t,this);var e={inner:{},outer:{}};e.inner={position:"",top:"",left:"",bottom:"",width:"",transform:""},e.outer={height:"",position:""};for(var i in e.outer)this.sidebar.style[i]=e.outer[i];for(var n in e.inner)this.sidebarInner.style[n]=e.inner[n];this.options.resizeSensor&&"undefined"!=typeof ResizeSensor&&(ResizeSensor.detach(this.sidebarInner,this.handleEvent),ResizeSensor.detach(this.container,this.handleEvent))}}],[{key:"supportTransform",value:function(t){var e=!1,i=t?"perspective":"transform",n=i.charAt(0).toUpperCase()+i.slice(1),o=["Webkit","Moz","O","ms"],s=document.createElement("support").style;return(i+" "+o.join(n+" ")+n).split(" ").forEach(function(t,i){if(void 0!==s[t])return e=t,!1}),e}},{key:"eventTrigger",value:function(t,e,i){try{var n=new CustomEvent(e,{detail:i})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(e,!0,!0,i)}t.dispatchEvent(n)}},{key:"extend",value:function(t,e){var i={};for(var n in t)void 0!==e[n]?i[n]=e[n]:i[n]=t[n];return i}},{key:"offsetRelative",value:function(t){var e={left:0,top:0};do{var i=t.offsetTop,n=t.offsetLeft;isNaN(i)||(e.top+=i),isNaN(n)||(e.left+=n),t="BODY"===t.tagName?t.parentElement:t.offsetParent}while(t);return e}},{key:"addClass",value:function(t,e){o.hasClass(t,e)||(t.classList?t.classList.add(e):t.className+=" "+e)}},{key:"removeClass",value:function(t,e){o.hasClass(t,e)&&(t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\b)"+e.split(" ").join("|")+"(\\b|$)","gi")," "))}},{key:"hasClass",value:function(t,e){return t.classList?t.classList.contains(e):new RegExp("(^| )"+e+"( |$)","gi").test(t.className)}},{key:"defaults",get:function(){return n}}]),o}()}();t.default=n,window.StickySidebar=n})});return t(i),t(e(function(t,e){!function(t,e){e(i)}(0,function(t){var e=function(t){return t&&t.__esModule?t:{default:t}}(t);!function(){if("undefined"!=typeof window){var t=window.$||window.jQuery||window.Zepto;if(t){t.fn.stickySidebar=function(i){return this.each(function(){var n=t(this),o=t(this).data("stickySidebar");if(o||(o=new e.default(this,"object"==typeof i&&i),n.data("stickySidebar",o)),"string"==typeof i){if(void 0===o[i]&&-1===["destroy","updateSticky"].indexOf(i))throw new Error('No method named "'+i+'"');o[i]()}})},t.fn.stickySidebar.Constructor=e.default;var i=t.fn.stickySidebar;t.fn.stickySidebar.noConflict=function(){return t.fn.stickySidebar=i,this}}}}()})}))}); \ No newline at end of file diff --git a/dist/sticky-sidebar.js b/dist/sticky-sidebar.js index 7052891..66d7912 100644 --- a/dist/sticky-sidebar.js +++ b/dist/sticky-sidebar.js @@ -1,368 +1,376 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.StickySidebar = factory()); -}(this, (function () { 'use strict'; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** - * Sticky Sidebar JavaScript Plugin. - * @version 3.3.1 - * @author Ahmed Bouhuolia - * @license The MIT License (MIT) - */ -var StickySidebar = function () { - - // --------------------------------- - // # Define Constants - // --------------------------------- - // - var EVENT_KEY = '.stickySidebar'; - var DEFAULTS = { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.StickySidebar = {}))); +}(this, (function (exports) { 'use strict'; - /** - * Additional top spacing of the element when it becomes sticky. - * @type {Numeric|Function} - */ - topSpacing: 0, +var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - /** - * Additional bottom spacing of the element when it becomes sticky. - * @type {Numeric|Function} - */ - bottomSpacing: 0, - /** - * Container sidebar selector to know what the beginning and end of sticky element. - * @type {String|False} - */ - containerSelector: false, - /** - * Inner wrapper selector. - * @type {String} - */ - innerWrapperSelector: '.inner-wrapper-sticky', +function unwrapExports (x) { + return x && x.__esModule ? x['default'] : x; +} - /** - * The name of CSS class to apply to elements when they have become stuck. - * @type {String|False} - */ - stickyClass: 'is-affixed', +function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; +} - /** - * Detect when sidebar and its container change height so re-calculate their dimensions. - * @type {Boolean} - */ - resizeSensor: true, +var stickySidebar = createCommonjsModule(function (module, exports) { +(function (global, factory) { + if (typeof undefined === "function" && undefined.amd) { + undefined(['exports'], factory); + } else { + factory(exports); + } +})(commonjsGlobal, function (exports) { + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + var _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } - /** - * The sidebar returns to its normal position if its width below this value. - * @type {Numeric} - */ - minWidth: false - }; + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); - // --------------------------------- - // # Class Definition - // --------------------------------- - // /** - * Sticky Sidebar Class. - * @public + * Sticky Sidebar JavaScript Plugin. + * @version 3.3.1 + * @author Ahmed Bouhuolia + * @license The MIT License (MIT) */ - var StickySidebar = function () { - /** - * Sticky Sidebar Constructor. - * @constructor - * @param {HTMLElement|String} sidebar - The sidebar element or sidebar selector. - * @param {Object} options - The options of sticky sidebar. - */ - function StickySidebar(sidebar) { - var _this = this; - - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - _classCallCheck(this, StickySidebar); - - this.options = StickySidebar.extend(DEFAULTS, options); - - // Sidebar element query if there's no one, throw error. - this.sidebar = 'string' === typeof sidebar ? document.querySelector(sidebar) : sidebar; - if ('undefined' === typeof this.sidebar) throw new Error("There is no specific sidebar element."); - - this.sidebarInner = false; - this.container = this.sidebar.parentElement; - - // Current Affix Type of sidebar element. - this.affixedType = 'STATIC'; - this.direction = 'down'; - this.support = { - transform: false, - transform3d: false - }; - - this._initialized = false; - this._reStyle = false; - this._breakpoint = false; - this._resizeListeners = []; - - // Dimensions of sidebar, container and screen viewport. - this.dimensions = { - translateY: 0, - topSpacing: 0, - lastTopSpacing: 0, - bottomSpacing: 0, - lastBottomSpacing: 0, - sidebarHeight: 0, - sidebarWidth: 0, - containerTop: 0, - containerHeight: 0, - viewportHeight: 0, - viewportTop: 0, - lastViewportTop: 0 - }; - - // Bind event handlers for referencability. - ['handleEvent'].forEach(function (method) { - _this[method] = _this[method].bind(_this); - }); - - // Initialize sticky sidebar for first time. - this.initialize(); - } - - /** - * Initializes the sticky sidebar by adding inner wrapper, define its container, - * min-width breakpoint, calculating dimensions, adding helper classes and inline style. - * @private - */ - - - _createClass(StickySidebar, [{ - key: 'initialize', - value: function initialize() { - var _this2 = this; - - this._setSupportFeatures(); - - // Get sticky sidebar inner wrapper, if not found, will create one. - if (this.options.innerWrapperSelector) { - this.sidebarInner = this.sidebar.querySelector(this.options.innerWrapperSelector); - - if (null === this.sidebarInner) this.sidebarInner = false; - } - - if (!this.sidebarInner) { - var wrapper = document.createElement('div'); - wrapper.setAttribute('class', 'inner-wrapper-sticky'); - this.sidebar.appendChild(wrapper); - - while (this.sidebar.firstChild != wrapper) { - wrapper.appendChild(this.sidebar.firstChild); - }this.sidebarInner = this.sidebar.querySelector('.inner-wrapper-sticky'); - } + // --------------------------------- + // # Define Constants + // --------------------------------- + // + var EVENT_KEY = '.stickySidebar'; + var DEFAULTS = { + /** + * Additional top spacing of the element when it becomes sticky. + * @type {Numeric|Function} + */ + topSpacing: 0, - // Container wrapper of the sidebar. - if (this.options.containerSelector) { - var containers = document.querySelectorAll(this.options.containerSelector); - containers = Array.prototype.slice.call(containers); + /** + * Additional bottom spacing of the element when it becomes sticky. + * @type {Numeric|Function} + */ + bottomSpacing: 0, - containers.forEach(function (container, item) { - if (!container.contains(_this2.sidebar)) return; - _this2.container = container; - }); + /** + * Container sidebar selector to know what the beginning and end of sticky element. + * @type {String|False} + */ + containerSelector: false, - if (!containers.length) throw new Error("The container does not contains on the sidebar."); - } + /** + * Inner wrapper selector. + * @type {String} + */ + innerWrapperSelector: '.inner-wrapper-sticky', - // If top/bottom spacing is not function parse value to integer. - if ('function' !== typeof this.options.topSpacing) this.options.topSpacing = parseInt(this.options.topSpacing) || 0; + /** + * The name of CSS class to apply to elements when they have become stuck. + * @type {String|False} + */ + stickyClass: 'is-affixed', - if ('function' !== typeof this.options.bottomSpacing) this.options.bottomSpacing = parseInt(this.options.bottomSpacing) || 0; + /** + * Detect when sidebar and its container change height so re-calculate their dimensions. + * @type {Boolean} + */ + resizeSensor: true, - // Breakdown sticky sidebar if screen width below `options.minWidth`. - this._widthBreakpoint(); + /** + * The sidebar returns to its normal position if its width below this value. + * @type {Numeric} + */ + minWidth: false + }; - // Calculate dimensions of sidebar, container and viewport. - this.calcDimensions(); + // --------------------------------- + // # Class Definition + // --------------------------------- + // + /** + * Sticky Sidebar Class. + * @public + */ - // Affix sidebar in proper position. - this.stickyPosition(); + var StickySidebar = function () { - // Bind all events. - this.bindEvents(); + /** + * Sticky Sidebar Constructor. + * @constructor + * @param {HTMLElement|String} sidebar - The sidebar element or sidebar selector. + * @param {Object} options - The options of sticky sidebar. + */ + function StickySidebar(sidebar) { + var _this = this; + + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, StickySidebar); + + this.options = StickySidebar.extend(DEFAULTS, options); + + // Sidebar element query if there's no one, throw error. + this.sidebar = 'string' === typeof sidebar ? document.querySelector(sidebar) : sidebar; + if ('undefined' === typeof this.sidebar) throw new Error("There is no specific sidebar element."); + + this.sidebarInner = false; + this.container = this.sidebar.parentElement; + + // Current Affix Type of sidebar element. + this.affixedType = 'STATIC'; + this.direction = 'down'; + this.support = { + transform: false, + transform3d: false + }; + + this._initialized = false; + this._reStyle = false; + this._breakpoint = false; + + // Dimensions of sidebar, container and screen viewport. + this.dimensions = { + translateY: 0, + maxTranslateY: 0, + topSpacing: 0, + lastTopSpacing: 0, + bottomSpacing: 0, + lastBottomSpacing: 0, + sidebarHeight: 0, + sidebarWidth: 0, + containerTop: 0, + containerHeight: 0, + viewportHeight: 0, + viewportTop: 0, + lastViewportTop: 0 + }; + + // Bind event handlers for referencability. + ['handleEvent'].forEach(function (method) { + _this[method] = _this[method].bind(_this); + }); - // Inform other properties the sticky sidebar is initialized. - this._initialized = true; + // Initialize sticky sidebar for first time. + this.initialize(); } /** - * Bind all events of sticky sidebar plugin. - * @protected + * Initializes the sticky sidebar by adding inner wrapper, define its container, + * min-width breakpoint, calculating dimensions, adding helper classes and inline style. + * @private */ - }, { - key: 'bindEvents', - value: function bindEvents() { - window.addEventListener('resize', this, { passive: true, capture: false }); - window.addEventListener('scroll', this, { passive: true, capture: false }); - this.sidebar.addEventListener('update' + EVENT_KEY, this); + _createClass(StickySidebar, [{ + key: 'initialize', + value: function initialize() { + var _this2 = this; - if (this.options.resizeSensor && 'undefined' !== typeof ResizeSensor) { - new ResizeSensor(this.sidebarInner, this.handleEvent); - new ResizeSensor(this.container, this.handleEvent); - } - } + this._setSupportFeatures(); - /** - * Handles all events of the plugin. - * @param {Object} event - Event object passed from listener. - */ + // Get sticky sidebar inner wrapper, if not found, will create one. + if (this.options.innerWrapperSelector) { + this.sidebarInner = this.sidebar.querySelector(this.options.innerWrapperSelector); - }, { - key: 'handleEvent', - value: function handleEvent(event) { - this.updateSticky(event); - } + if (null === this.sidebarInner) this.sidebarInner = false; + } - /** - * Calculates dimensions of sidebar, container and screen viewpoint - * @public - */ + if (!this.sidebarInner) { + var wrapper = document.createElement('div'); + wrapper.setAttribute('class', 'inner-wrapper-sticky'); + this.sidebar.appendChild(wrapper); - }, { - key: 'calcDimensions', - value: function calcDimensions() { - if (this._breakpoint) return; - var dims = this.dimensions; + while (this.sidebar.firstChild != wrapper) { + wrapper.appendChild(this.sidebar.firstChild); + }this.sidebarInner = this.sidebar.querySelector('.inner-wrapper-sticky'); + } - // Container of sticky sidebar dimensions. - dims.containerTop = StickySidebar.offsetRelative(this.container).top; - dims.containerHeight = this.container.clientHeight; - dims.containerBottom = dims.containerTop + dims.containerHeight; + // Container wrapper of the sidebar. + if (this.options.containerSelector) { + var containers = document.querySelectorAll(this.options.containerSelector); + containers = Array.prototype.slice.call(containers); - // Sidebar dimensions. - dims.sidebarHeight = this.sidebarInner.offsetHeight; - dims.sidebarWidth = this.sidebarInner.offsetWidth; + containers.forEach(function (container, item) { + if (!container.contains(_this2.sidebar)) return; + _this2.container = container; + }); - // Screen viewport dimensions. - dims.viewportHeight = window.innerHeight; + if (!containers.length) throw new Error("The container does not contains on the sidebar."); + } - this._calcDimensionsWithScroll(); - } + // If top/bottom spacing is not function parse value to integer. + if ('function' !== typeof this.options.topSpacing) this.options.topSpacing = parseInt(this.options.topSpacing) || 0; - /** - * Some dimensions values need to be up-to-date when scrolling the page. - * @private - */ + if ('function' !== typeof this.options.bottomSpacing) this.options.bottomSpacing = parseInt(this.options.bottomSpacing) || 0; - }, { - key: '_calcDimensionsWithScroll', - value: function _calcDimensionsWithScroll() { - var dims = this.dimensions; + // Breakdown sticky sidebar if screen width below `options.minWidth`. + this._widthBreakpoint(); - dims.sidebarLeft = StickySidebar.offsetRelative(this.sidebar).left; + // Calculate dimensions of sidebar, container and viewport. + this.calcDimensions(); - dims.viewportTop = document.documentElement.scrollTop || document.body.scrollTop; - dims.viewportBottom = dims.viewportTop + dims.viewportHeight; - dims.viewportLeft = document.documentElement.scrollLeft || document.body.scrollLeft; + // Affix sidebar in proper position. + this.stickyPosition(); - dims.topSpacing = this.options.topSpacing; - dims.bottomSpacing = this.options.bottomSpacing; + // Bind all events. + this.bindEvents(); - if ('function' === typeof dims.topSpacing) dims.topSpacing = parseInt(dims.topSpacing(this.sidebar)) || 0; + // Inform other properties the sticky sidebar is initialized. + this._initialized = true; + } + }, { + key: 'bindEvents', + value: function bindEvents() { + window.addEventListener('resize', this, { passive: true, capture: false }); + window.addEventListener('scroll', this, { passive: true, capture: false }); - if ('function' === typeof dims.bottomSpacing) dims.bottomSpacing = parseInt(dims.bottomSpacing(this.sidebar)) || 0; + this.sidebar.addEventListener('update' + EVENT_KEY, this); - if ('VIEWPORT-TOP' === this.affixedType) { - // Adjust translate Y in the case decrease top spacing value. - if (dims.topSpacing < dims.lastTopSpacing) { - dims.translateY += dims.lastTopSpacing - dims.topSpacing; - this._reStyle = true; - } - } else if ('VIEWPORT-BOTTOM' === this.affixedType) { - // Adjust translate Y in the case decrease bottom spacing value. - if (dims.bottomSpacing < dims.lastBottomSpacing) { - dims.translateY += dims.lastBottomSpacing - dims.bottomSpacing; - this._reStyle = true; + if (this.options.resizeSensor && 'undefined' !== typeof ResizeSensor) { + new ResizeSensor(this.sidebarInner, this.handleEvent); + new ResizeSensor(this.container, this.handleEvent); } } + }, { + key: 'handleEvent', + value: function handleEvent(event) { + this.updateSticky(event); + } + }, { + key: 'calcDimensions', + value: function calcDimensions() { + if (this._breakpoint) return; + var dims = this.dimensions; - dims.lastTopSpacing = dims.topSpacing; - dims.lastBottomSpacing = dims.bottomSpacing; - } + // Container of sticky sidebar dimensions. + dims.containerTop = StickySidebar.offsetRelative(this.container).top; + dims.containerHeight = this.container.clientHeight; + dims.containerBottom = dims.containerTop + dims.containerHeight; - /** - * Determine whether the sidebar is bigger than viewport. - * @public - * @return {Boolean} - */ + // Sidebar dimensions. + dims.sidebarHeight = this.sidebarInner.offsetHeight; + dims.sidebarWidth = this.sidebarInner.offsetWidth; - }, { - key: 'isSidebarFitsViewport', - value: function isSidebarFitsViewport() { - return this.dimensions.sidebarHeight < this.dimensions.viewportHeight; - } + // Screen viewport dimensions. + dims.viewportHeight = window.innerHeight; - /** - * Observe browser scrolling direction top and down. - */ + // Maximum sidebar translate Y. + dims.maxTranslateY = dims.containerHeight - dims.sidebarHeight; - }, { - key: 'observeScrollDir', - value: function observeScrollDir() { - var dims = this.dimensions; - if (dims.lastViewportTop === dims.viewportTop) return; + this._calcDimensionsWithScroll(); + } + }, { + key: '_calcDimensionsWithScroll', + value: function _calcDimensionsWithScroll() { + var dims = this.dimensions; - var furthest = 'down' === this.direction ? Math.min : Math.max; + dims.sidebarLeft = StickySidebar.offsetRelative(this.sidebar).left; - // If the browser is scrolling not in the same direction. - if (dims.viewportTop === furthest(dims.viewportTop, dims.lastViewportTop)) this.direction = 'down' === this.direction ? 'up' : 'down'; - } + dims.viewportTop = document.documentElement.scrollTop || document.body.scrollTop; + dims.viewportBottom = dims.viewportTop + dims.viewportHeight; + dims.viewportLeft = document.documentElement.scrollLeft || document.body.scrollLeft; - /** - * Gets affix type of sidebar according to current scrollTop and scrollLeft. - * Holds all logical affix of the sidebar when scrolling up and down and when sidebar - * is bigger than viewport and vice versa. - * @public - * @return {String|False} - Proper affix type. - */ + dims.topSpacing = this.options.topSpacing; + dims.bottomSpacing = this.options.bottomSpacing; + + if ('function' === typeof dims.topSpacing) dims.topSpacing = parseInt(dims.topSpacing(this.sidebar)) || 0; - }, { - key: 'getAffixType', - value: function getAffixType() { - var dims = this.dimensions, - affixType = false; + if ('function' === typeof dims.bottomSpacing) dims.bottomSpacing = parseInt(dims.bottomSpacing(this.sidebar)) || 0; - this._calcDimensionsWithScroll(); + if ('VIEWPORT-TOP' === this.affixedType) { + // Adjust translate Y in the case decrease top spacing value. + if (dims.topSpacing < dims.lastTopSpacing) { + dims.translateY += dims.lastTopSpacing - dims.topSpacing; + this._reStyle = true; + } + } else if ('VIEWPORT-BOTTOM' === this.affixedType) { + // Adjust translate Y in the case decrease bottom spacing value. + if (dims.bottomSpacing < dims.lastBottomSpacing) { + dims.translateY += dims.lastBottomSpacing - dims.bottomSpacing; + this._reStyle = true; + } + } + + dims.lastTopSpacing = dims.topSpacing; + dims.lastBottomSpacing = dims.bottomSpacing; + } + }, { + key: 'isSidebarFitsViewport', + value: function isSidebarFitsViewport() { + return this.dimensions.sidebarHeight < this.dimensions.viewportHeight; + } + }, { + key: 'observeScrollDir', + value: function observeScrollDir() { + var dims = this.dimensions; + if (dims.lastViewportTop === dims.viewportTop) return; - var sidebarBottom = dims.sidebarHeight + dims.containerTop; - var colliderTop = dims.viewportTop + dims.topSpacing; - var colliderBottom = dims.viewportBottom - dims.bottomSpacing; + var furthest = 'down' === this.direction ? Math.min : Math.max; - // When browser is scrolling top. - if ('up' === this.direction) { - if (colliderTop <= dims.containerTop) { + // If the browser is scrolling not in the same direction. + if (dims.viewportTop === furthest(dims.viewportTop, dims.lastViewportTop)) this.direction = 'down' === this.direction ? 'up' : 'down'; + } + }, { + key: 'getAffixType', + value: function getAffixType() { + this._calcDimensionsWithScroll(); + var dims = this.dimensions; + var colliderTop = dims.viewportTop + dims.topSpacing; + var affixType = this.affixedType; + + if (colliderTop <= dims.containerTop || dims.containerHeight <= dims.sidebarHeight) { dims.translateY = 0; affixType = 'STATIC'; - } else if (colliderTop <= dims.translateY + dims.containerTop) { - dims.translateY = colliderTop - dims.containerTop; - affixType = 'VIEWPORT-TOP'; - } else if (!this.isSidebarFitsViewport() && dims.containerTop <= colliderTop) { - affixType = 'VIEWPORT-UNBOTTOM'; + } else { + affixType = 'up' === this.direction ? this._getAffixTypeScrollingUp() : this._getAffixTypeScrollingDown(); } - // When browser is scrolling up. - } else { - // When sidebar element is not bigger than screen viewport. - if (this.isSidebarFitsViewport()) { + // Make sure the translate Y is not bigger than container height. + dims.translateY = Math.max(0, dims.translateY); + dims.translateY = Math.min(dims.containerHeight, dims.translateY); + dims.translateY = Math.round(dims.translateY); + + dims.lastViewportTop = dims.viewportTop; + return affixType; + } + }, { + key: '_getAffixTypeScrollingDown', + value: function _getAffixTypeScrollingDown() { + var dims = this.dimensions; + var sidebarBottom = dims.sidebarHeight + dims.containerTop; + var colliderTop = dims.viewportTop + dims.topSpacing; + var colliderBottom = dims.viewportBottom - dims.bottomSpacing; + var affixType = this.affixedType; + + if (this.isSidebarFitsViewport()) { if (dims.sidebarHeight + colliderTop >= dims.containerBottom) { dims.translateY = dims.containerBottom - sidebarBottom; affixType = 'CONTAINER-BOTTOM'; @@ -370,388 +378,311 @@ var StickySidebar = function () { dims.translateY = colliderTop - dims.containerTop; affixType = 'VIEWPORT-TOP'; } - // When sidebar element is bigger than screen viewport. } else { - if (dims.containerBottom <= colliderBottom) { dims.translateY = dims.containerBottom - sidebarBottom; affixType = 'CONTAINER-BOTTOM'; } else if (sidebarBottom + dims.translateY <= colliderBottom) { dims.translateY = colliderBottom - sidebarBottom; affixType = 'VIEWPORT-BOTTOM'; - } else if (dims.containerTop + dims.translateY <= colliderTop) { + } else if (dims.containerTop + dims.translateY <= colliderTop && 0 !== dims.translateY && dims.maxTranslateY !== dims.translateY) { affixType = 'VIEWPORT-UNBOTTOM'; } } + + return affixType; } + }, { + key: '_getAffixTypeScrollingUp', + value: function _getAffixTypeScrollingUp() { + var dims = this.dimensions; + var sidebarBottom = dims.sidebarHeight + dims.containerTop; + var colliderTop = dims.viewportTop + dims.topSpacing; + var colliderBottom = dims.viewportBottom - dims.bottomSpacing; + var affixType = this.affixedType; + + if (colliderTop <= dims.translateY + dims.containerTop) { + dims.translateY = colliderTop - dims.containerTop; + affixType = 'VIEWPORT-TOP'; + } else if (dims.containerBottom <= colliderBottom) { + dims.translateY = dims.containerBottom - sidebarBottom; + affixType = 'CONTAINER-BOTTOM'; + } else if (!this.isSidebarFitsViewport()) { - // Make sure the translate Y is not bigger than container height. - dims.translateY = Math.max(0, dims.translateY); - dims.translateY = Math.min(dims.containerHeight, dims.translateY); + if (dims.containerTop <= colliderTop && 0 !== dims.translateY && dims.maxTranslateY !== dims.translateY) { + affixType = 'VIEWPORT-UNBOTTOM'; + } + } - dims.lastViewportTop = dims.viewportTop; - return affixType; - } + return affixType; + } + }, { + key: '_getStyle', + value: function _getStyle(affixType) { + if ('undefined' === typeof affixType) return; + + var style = { inner: {}, outer: {} }; + var dims = this.dimensions; + + switch (affixType) { + case 'VIEWPORT-TOP': + style.inner = { position: 'fixed', top: dims.topSpacing, + left: dims.sidebarLeft - dims.viewportLeft, width: dims.sidebarWidth }; + break; + case 'VIEWPORT-BOTTOM': + style.inner = { position: 'fixed', top: 'auto', left: dims.sidebarLeft, + bottom: dims.bottomSpacing, width: dims.sidebarWidth }; + break; + case 'CONTAINER-BOTTOM': + case 'VIEWPORT-UNBOTTOM': + var translate = this._getTranslate(0, dims.translateY + 'px'); + + if (translate) style.inner = { transform: translate };else style.inner = { position: 'absolute', top: dims.translateY, width: dims.sidebarWidth }; + break; + } - /** - * Gets inline style of sticky sidebar wrapper and inner wrapper according - * to its affix type. - * @private - * @param {String} affixType - Affix type of sticky sidebar. - * @return {Object} - */ + switch (affixType) { + case 'VIEWPORT-TOP': + case 'VIEWPORT-BOTTOM': + case 'VIEWPORT-UNBOTTOM': + case 'CONTAINER-BOTTOM': + style.outer = { height: dims.sidebarHeight, position: 'relative' }; + break; + } - }, { - key: '_getStyle', - value: function _getStyle(affixType) { - if ('undefined' === typeof affixType) return; - - var style = { inner: {}, outer: {} }; - var dims = this.dimensions; - - switch (affixType) { - case 'VIEWPORT-TOP': - style.inner = { position: 'fixed', top: dims.topSpacing, - left: dims.sidebarLeft - dims.viewportLeft, width: dims.sidebarWidth }; - break; - case 'VIEWPORT-BOTTOM': - style.inner = { position: 'fixed', top: 'auto', left: dims.sidebarLeft, - bottom: dims.bottomSpacing, width: dims.sidebarWidth }; - break; - case 'CONTAINER-BOTTOM': - case 'VIEWPORT-UNBOTTOM': - var translate = this._getTranslate(0, dims.translateY + 'px'); - - if (translate) style.inner = { transform: translate };else style.inner = { position: 'absolute', top: dims.translateY, width: dims.sidebarWidth }; - break; - } + style.outer = StickySidebar.extend({ height: '', position: '' }, style.outer); + style.inner = StickySidebar.extend({ position: 'relative', top: '', left: '', + bottom: '', width: '', transform: '' }, style.inner); - switch (affixType) { - case 'VIEWPORT-TOP': - case 'VIEWPORT-BOTTOM': - case 'VIEWPORT-UNBOTTOM': - case 'CONTAINER-BOTTOM': - style.outer = { height: dims.sidebarHeight, position: 'relative' }; - break; + return style; } + }, { + key: 'stickyPosition', + value: function stickyPosition(force) { + if (this._breakpoint) return; - style.outer = StickySidebar.extend({ height: '', position: '' }, style.outer); - style.inner = StickySidebar.extend({ position: 'relative', top: '', left: '', - bottom: '', width: '', transform: this._getTranslate() }, style.inner); + force = this._reStyle || force || false; - return style; - } + var affixType = this.getAffixType(); + var style = this._getStyle(affixType); - /** - * Cause the sidebar to be sticky according to affix type by adding inline - * style, adding helper class and trigger events. - * @function - * @protected - * @param {string} force - Update sticky sidebar position by force. - */ + if ((this.affixedType != affixType || force) && affixType) { + var affixEvent = 'affix.' + affixType.toLowerCase().replace('viewport-', '') + EVENT_KEY; + StickySidebar.eventTrigger(this.sidebar, affixEvent); - }, { - key: 'stickyPosition', - value: function stickyPosition(force) { - if (this._breakpoint) return; + if ('STATIC' === affixType) StickySidebar.removeClass(this.sidebar, this.options.stickyClass);else StickySidebar.addClass(this.sidebar, this.options.stickyClass); - force = this._reStyle || force || false; + for (var key in style.outer) { + var unit = 'number' === typeof style.outer[key] ? 'px' : ''; + this.sidebar.style[key] = style.outer[key] + unit; + } - var affixType = this.getAffixType(); - var style = this._getStyle(affixType); + for (var _key in style.inner) { + var _unit = 'number' === typeof style.inner[_key] ? 'px' : ''; + this.sidebarInner.style[_key] = style.inner[_key] + _unit; + } - if ((this.affixedType != affixType || force) && affixType) { - var affixEvent = 'affix.' + affixType.toLowerCase().replace('viewport-', '') + EVENT_KEY; - StickySidebar.eventTrigger(this.sidebar, affixEvent); + var affixedEvent = 'affixed.' + affixType.toLowerCase().replace('viewport-', '') + EVENT_KEY; + StickySidebar.eventTrigger(this.sidebar, affixedEvent); + } else { + if (this._initialized) this.sidebarInner.style.left = style.inner.left; + } - if ('STATIC' === affixType) StickySidebar.removeClass(this.sidebar, this.options.stickyClass);else StickySidebar.addClass(this.sidebar, this.options.stickyClass); + this.affixedType = affixType; + } + }, { + key: '_widthBreakpoint', + value: function _widthBreakpoint() { - for (var key in style.outer) { - this.sidebar.style[key] = style.outer[key]; - } + if (window.innerWidth <= this.options.minWidth) { + this._breakpoint = true; + this.affixedType = 'STATIC'; - for (var _key in style.inner) { - var _unit2 = 'number' === typeof style.inner[_key] ? 'px' : ''; - this.sidebarInner.style[_key] = style.inner[_key] + _unit2; + this.sidebar.removeAttribute('style'); + StickySidebar.removeClass(this.sidebar, this.options.stickyClass); + this.sidebarInner.removeAttribute('style'); + } else { + this._breakpoint = false; } + } + }, { + key: 'updateSticky', + value: function updateSticky() { + var _this3 = this; + + var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + if (this._running) return; + this._running = true; + + (function (eventType) { + requestAnimationFrame(function () { + switch (eventType) { + // When browser is scrolling and re-calculate just dimensions + // within scroll. + case 'scroll': + _this3._calcDimensionsWithScroll(); + _this3.observeScrollDir(); + _this3.stickyPosition(); + break; + + // When browser is resizing or there's no event, observe width + // breakpoint and re-calculate dimensions. + case 'resize': + default: + _this3._widthBreakpoint(); + _this3.calcDimensions(); + _this3.stickyPosition(true); + break; + } + _this3._running = false; + }); + })(event.type); + } + }, { + key: '_setSupportFeatures', + value: function _setSupportFeatures() { + var support = this.support; - var affixedEvent = 'affixed.' + affixType.toLowerCase().replace('viewport-', '') + EVENT_KEY; - StickySidebar.eventTrigger(this.sidebar, affixedEvent); - } else { - if (this._initialized) this.sidebarInner.style.left = style.inner.left; + support.transform = StickySidebar.supportTransform(); + support.transform3d = StickySidebar.supportTransform(true); + } + }, { + key: '_getTranslate', + value: function _getTranslate() { + var y = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var z = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + + if (this.support.transform3d) return 'translate3d(' + y + ', ' + x + ', ' + z + ')';else if (this.support.translate) return 'translate(' + y + ', ' + x + ')';else return false; } + }, { + key: 'destroy', + value: function destroy() { + window.removeEventListener('resize', this, { capture: false }); + window.removeEventListener('scroll', this, { capture: false }); - this.affixedType = affixType; - } + this.sidebar.classList.remove(this.options.stickyClass); + this.sidebar.style.minHeight = ''; - /** - * Breakdown sticky sidebar when window width is below `options.minWidth` value. - * @protected - */ + this.sidebar.removeEventListener('update' + EVENT_KEY, this); - }, { - key: '_widthBreakpoint', - value: function _widthBreakpoint() { + var styleReset = { inner: {}, outer: {} }; - if (window.innerWidth <= this.options.minWidth) { - this._breakpoint = true; - this.affixedType = 'STATIC'; + styleReset.inner = { position: '', top: '', left: '', bottom: '', width: '', transform: '' }; + styleReset.outer = { height: '', position: '' }; - this.sidebar.removeAttribute('style'); - StickySidebar.removeClass(this.sidebar, this.options.stickyClass); - this.sidebarInner.removeAttribute('style'); - } else { - this._breakpoint = false; + for (var key in styleReset.outer) { + this.sidebar.style[key] = styleReset.outer[key]; + }for (var _key2 in styleReset.inner) { + this.sidebarInner.style[_key2] = styleReset.inner[_key2]; + }if (this.options.resizeSensor && 'undefined' !== typeof ResizeSensor) { + ResizeSensor.detach(this.sidebarInner, this.handleEvent); + ResizeSensor.detach(this.container, this.handleEvent); + } } - } - - /** - * Switches between functions stack for each event type, if there's no - * event, it will re-initialize sticky sidebar. - * @public - */ - - }, { - key: 'updateSticky', - value: function updateSticky() { - var _this3 = this; - - var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - - if (this._running) return; - this._running = true; - - (function (eventType) { - - requestAnimationFrame(function () { - switch (eventType) { - // When browser is scrolling and re-calculate just dimensions - // within scroll. - case 'scroll': - _this3._calcDimensionsWithScroll(); - _this3.observeScrollDir(); - _this3.stickyPosition(); - break; - - // When browser is resizing or there's no event, observe width - // breakpoint and re-calculate dimensions. - case 'resize': - default: - _this3._widthBreakpoint(); - _this3.calcDimensions(); - _this3.stickyPosition(true); - break; + }], [{ + key: 'supportTransform', + value: function supportTransform(transform3d) { + var result = false, + property = transform3d ? 'perspective' : 'transform', + upper = property.charAt(0).toUpperCase() + property.slice(1), + prefixes = ['Webkit', 'Moz', 'O', 'ms'], + support = document.createElement('support'), + style = support.style; + + (property + ' ' + prefixes.join(upper + ' ') + upper).split(' ').forEach(function (property, i) { + if (style[property] !== undefined) { + result = property; + return false; } - _this3._running = false; }); - })(event.type); - } - - /** - * Set browser support features to the public property. - * @private - */ - - }, { - key: '_setSupportFeatures', - value: function _setSupportFeatures() { - var support = this.support; - - support.transform = StickySidebar.supportTransform(); - support.transform3d = StickySidebar.supportTransform(true); - } - - /** - * Get translate value, if the browser supports transfrom3d, it will adopt it. - * and the same with translate. if browser doesn't support both return false. - * @param {Number} y - Value of Y-axis. - * @param {Number} x - Value of X-axis. - * @param {Number} z - Value of Z-axis. - * @return {String|False} - */ - - }, { - key: '_getTranslate', - value: function _getTranslate() { - var y = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - var x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - var z = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; - - if (this.support.transform3d) return 'translate3d(' + y + ', ' + x + ', ' + z + ')';else if (this.support.translate) return 'translate(' + y + ', ' + x + ')';else return false; - } - - /** - * Destroy sticky sidebar plugin. - * @public - */ - - }, { - key: 'destroy', - value: function destroy() { - window.removeEventListener('resize', this, { caption: false }); - window.removeEventListener('scroll', this, { caption: false }); - - this.sidebar.classList.remove(this.options.stickyClass); - this.sidebar.style.minHeight = ''; - - this.sidebar.removeEventListener('update' + EVENT_KEY, this); - - var styleReset = { inner: {}, outer: {} }; - - styleReset.inner = { position: '', top: '', left: '', bottom: '', width: '', transform: '' }; - styleReset.outer = { height: '', position: '' }; - - for (var key in styleReset.outer) { - this.sidebar.style[key] = styleReset.outer[key]; - }for (var _key2 in styleReset.inner) { - this.sidebarInner.style[_key2] = styleReset.inner[_key2]; - }if (this.options.resizeSensor && 'undefined' !== typeof ResizeSensor) { - ResizeSensor.detach(this.sidebarInner, this.handleEvent); - ResizeSensor.detach(this.container, this.handleEvent); + return result; } - } - - /** - * Determine if the browser supports CSS transform feature. - * @function - * @static - * @param {Boolean} transform3d - Detect transform with translate3d. - * @return {String} - */ - - }], [{ - key: 'supportTransform', - value: function supportTransform(transform3d) { - var result = false, - property = transform3d ? 'perspective' : 'transform', - upper = property.charAt(0).toUpperCase() + property.slice(1), - prefixes = ['Webkit', 'Moz', 'O', 'ms'], - support = document.createElement('support'), - style = support.style; - - (property + ' ' + prefixes.join(upper + ' ') + upper).split(' ').forEach(function (property, i) { - if (style[property] !== undefined) { - result = property; - return false; + }, { + key: 'eventTrigger', + value: function eventTrigger(element, eventName, data) { + try { + var event = new CustomEvent(eventName, { detail: data }); + } catch (e) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent(eventName, true, true, data); } - }); - return result; - } - - /** - * Trigger custom event. - * @static - * @param {DOMObject} element - Target element on the DOM. - * @param {String} eventName - Event name. - * @param {Object} data - - */ - - }, { - key: 'eventTrigger', - value: function eventTrigger(element, eventName, data) { - try { - var event = new CustomEvent(eventName, { detail: data }); - } catch (e) { - var event = document.createEvent('CustomEvent'); - event.initCustomEvent(eventName, true, true, data); + element.dispatchEvent(event); } - element.dispatchEvent(event); - } - - /** - * Extend options object with defaults. - * @function - * @static - */ - - }, { - key: 'extend', - value: function extend(defaults, options) { - var results = {}; - for (var key in defaults) { - if ('undefined' !== typeof options[key]) results[key] = options[key];else results[key] = defaults[key]; + }, { + key: 'extend', + value: function extend(defaults, options) { + var results = {}; + for (var key in defaults) { + if ('undefined' !== typeof options[key]) results[key] = options[key];else results[key] = defaults[key]; + } + return results; } - return results; - } + }, { + key: 'offsetRelative', + value: function offsetRelative(element) { + var result = { left: 0, top: 0 }; - /** - * Get current coordinates left and top of specific element. - * @static - */ + do { + var offsetTop = element.offsetTop; + var offsetLeft = element.offsetLeft; - }, { - key: 'offsetRelative', - value: function offsetRelative(element) { - var result = { left: 0, top: 0 }; + if (!isNaN(offsetTop)) result.top += offsetTop; - do { - var offsetTop = element.offsetTop; - var offsetLeft = element.offsetLeft; + if (!isNaN(offsetLeft)) result.left += offsetLeft; - if (!isNaN(offsetTop)) result.top += offsetTop; - - if (!isNaN(offsetLeft)) result.left += offsetLeft; - - element = 'BODY' === element.tagName ? element.parentElement : element.offsetParent; - } while (element); - return result; - } - - /** - * Add specific class name to specific element. - * @static - * @param {ObjectDOM} element - * @param {String} className - */ - - }, { - key: 'addClass', - value: function addClass(element, className) { - if (!StickySidebar.hasClass(element, className)) { - if (element.classList) element.classList.add(className);else element.className += ' ' + className; + element = 'BODY' === element.tagName ? element.parentElement : element.offsetParent; + } while (element); + return result; } - } - - /** - * Remove specific class name to specific element - * @static - * @param {ObjectDOM} element - * @param {String} className - */ - - }, { - key: 'removeClass', - value: function removeClass(element, className) { - if (StickySidebar.hasClass(element, className)) { - if (element.classList) element.classList.remove(className);else element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); + }, { + key: 'addClass', + value: function addClass(element, className) { + if (!StickySidebar.hasClass(element, className)) { + if (element.classList) element.classList.add(className);else element.className += ' ' + className; + } } - } - - /** - * Determine weather the element has specific class name. - * @static - * @param {ObjectDOM} element - * @param {String} className - */ + }, { + key: 'removeClass', + value: function removeClass(element, className) { + if (StickySidebar.hasClass(element, className)) { + if (element.classList) element.classList.remove(className);else element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); + } + } + }, { + key: 'hasClass', + value: function hasClass(element, className) { + if (element.classList) return element.classList.contains(className);else return new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className); + } + }, { + key: 'defaults', + get: function () { + return DEFAULTS; + } + }]); - }, { - key: 'hasClass', - value: function hasClass(element, className) { - if (element.classList) return element.classList.contains(className);else return new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className); - } - }]); + return StickySidebar; + }(); return StickySidebar; }(); - return StickySidebar; -}(); + exports.default = StickySidebar; + + + // Global + // ------------------------- + window.StickySidebar = StickySidebar; +}); +}); + +var stickySidebar$1 = unwrapExports(stickySidebar); -// Global -// ------------------------- -window.StickySidebar = StickySidebar; +exports['default'] = stickySidebar$1; +exports.__moduleExports = stickySidebar; -return StickySidebar; +Object.defineProperty(exports, '__esModule', { value: true }); }))); diff --git a/dist/sticky-sidebar.js.map b/dist/sticky-sidebar.js.map index f73e1aa..7fa344f 100644 --- a/dist/sticky-sidebar.js.map +++ b/dist/sticky-sidebar.js.map @@ -1 +1 @@ -{"version":3,"file":"sticky-sidebar.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file +{"version":3,"file":"sticky-sidebar.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/dist/sticky-sidebar.min.js b/dist/sticky-sidebar.min.js index 502182a..40f581b 100644 --- a/dist/sticky-sidebar.min.js +++ b/dist/sticky-sidebar.min.js @@ -5,4 +5,4 @@ * @author Ahmed Bouhuolia * @license The MIT License (MIT) **/ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.StickySidebar=e()}(this,function(){"use strict";var t=function(){function t(t,e){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{};if(function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,n),this.options=n.extend(i,s),this.sidebar="string"==typeof t?document.querySelector(t):t,void 0===this.sidebar)throw new Error("There is no specific sidebar element.");this.sidebarInner=!1,this.container=this.sidebar.parentElement,this.affixedType="STATIC",this.direction="down",this.support={transform:!1,transform3d:!1},this._initialized=!1,this._reStyle=!1,this._breakpoint=!1,this._resizeListeners=[],this.dimensions={translateY:0,topSpacing:0,lastTopSpacing:0,bottomSpacing:0,lastBottomSpacing:0,sidebarHeight:0,sidebarWidth:0,containerTop:0,containerHeight:0,viewportHeight:0,viewportTop:0,lastViewportTop:0},["handleEvent"].forEach(function(t){e[t]=e[t].bind(e)}),this.initialize()}return t(n,[{key:"initialize",value:function(){var t=this;if(this._setSupportFeatures(),this.options.innerWrapperSelector&&(this.sidebarInner=this.sidebar.querySelector(this.options.innerWrapperSelector),null===this.sidebarInner&&(this.sidebarInner=!1)),!this.sidebarInner){var e=document.createElement("div");for(e.setAttribute("class","inner-wrapper-sticky"),this.sidebar.appendChild(e);this.sidebar.firstChild!=e;)e.appendChild(this.sidebar.firstChild);this.sidebarInner=this.sidebar.querySelector(".inner-wrapper-sticky")}if(this.options.containerSelector){var i=document.querySelectorAll(this.options.containerSelector);if((i=Array.prototype.slice.call(i)).forEach(function(e,i){e.contains(t.sidebar)&&(t.container=e)}),!i.length)throw new Error("The container does not contains on the sidebar.")}"function"!=typeof this.options.topSpacing&&(this.options.topSpacing=parseInt(this.options.topSpacing)||0),"function"!=typeof this.options.bottomSpacing&&(this.options.bottomSpacing=parseInt(this.options.bottomSpacing)||0),this._widthBreakpoint(),this.calcDimensions(),this.stickyPosition(),this.bindEvents(),this._initialized=!0}},{key:"bindEvents",value:function(){window.addEventListener("resize",this,{passive:!0,capture:!1}),window.addEventListener("scroll",this,{passive:!0,capture:!1}),this.sidebar.addEventListener("update"+e,this),this.options.resizeSensor&&"undefined"!=typeof ResizeSensor&&(new ResizeSensor(this.sidebarInner,this.handleEvent),new ResizeSensor(this.container,this.handleEvent))}},{key:"handleEvent",value:function(t){this.updateSticky(t)}},{key:"calcDimensions",value:function(){if(!this._breakpoint){var t=this.dimensions;t.containerTop=n.offsetRelative(this.container).top,t.containerHeight=this.container.clientHeight,t.containerBottom=t.containerTop+t.containerHeight,t.sidebarHeight=this.sidebarInner.offsetHeight,t.sidebarWidth=this.sidebarInner.offsetWidth,t.viewportHeight=window.innerHeight,this._calcDimensionsWithScroll()}}},{key:"_calcDimensionsWithScroll",value:function(){var t=this.dimensions;t.sidebarLeft=n.offsetRelative(this.sidebar).left,t.viewportTop=document.documentElement.scrollTop||document.body.scrollTop,t.viewportBottom=t.viewportTop+t.viewportHeight,t.viewportLeft=document.documentElement.scrollLeft||document.body.scrollLeft,t.topSpacing=this.options.topSpacing,t.bottomSpacing=this.options.bottomSpacing,"function"==typeof t.topSpacing&&(t.topSpacing=parseInt(t.topSpacing(this.sidebar))||0),"function"==typeof t.bottomSpacing&&(t.bottomSpacing=parseInt(t.bottomSpacing(this.sidebar))||0),"VIEWPORT-TOP"===this.affixedType?t.topSpacing=t.containerBottom?(t.translateY=t.containerBottom-i,e="CONTAINER-BOTTOM"):n>=t.containerTop&&(t.translateY=n-t.containerTop,e="VIEWPORT-TOP"):t.containerBottom<=s?(t.translateY=t.containerBottom-i,e="CONTAINER-BOTTOM"):i+t.translateY<=s?(t.translateY=s-i,e="VIEWPORT-BOTTOM"):t.containerTop+t.translateY<=n&&(e="VIEWPORT-UNBOTTOM"),t.translateY=Math.max(0,t.translateY),t.translateY=Math.min(t.containerHeight,t.translateY),t.lastViewportTop=t.viewportTop,e}},{key:"_getStyle",value:function(t){if(void 0!==t){var e={inner:{},outer:{}},i=this.dimensions;switch(t){case"VIEWPORT-TOP":e.inner={position:"fixed",top:i.topSpacing,left:i.sidebarLeft-i.viewportLeft,width:i.sidebarWidth};break;case"VIEWPORT-BOTTOM":e.inner={position:"fixed",top:"auto",left:i.sidebarLeft,bottom:i.bottomSpacing,width:i.sidebarWidth};break;case"CONTAINER-BOTTOM":case"VIEWPORT-UNBOTTOM":var s=this._getTranslate(0,i.translateY+"px");e.inner=s?{transform:s}:{position:"absolute",top:i.translateY,width:i.sidebarWidth}}switch(t){case"VIEWPORT-TOP":case"VIEWPORT-BOTTOM":case"VIEWPORT-UNBOTTOM":case"CONTAINER-BOTTOM":e.outer={height:i.sidebarHeight,position:"relative"}}return e.outer=n.extend({height:"",position:""},e.outer),e.inner=n.extend({position:"relative",top:"",left:"",bottom:"",width:"",transform:this._getTranslate()},e.inner),e}}},{key:"stickyPosition",value:function(t){if(!this._breakpoint){t=this._reStyle||t||!1;var i=this.getAffixType(),s=this._getStyle(i);if((this.affixedType!=i||t)&&i){var o="affix."+i.toLowerCase().replace("viewport-","")+e;n.eventTrigger(this.sidebar,o),"STATIC"===i?n.removeClass(this.sidebar,this.options.stickyClass):n.addClass(this.sidebar,this.options.stickyClass);for(var r in s.outer)this.sidebar.style[r]=s.outer[r];for(var a in s.inner){var p="number"==typeof s.inner[a]?"px":"";this.sidebarInner.style[a]=s.inner[a]+p}var c="affixed."+i.toLowerCase().replace("viewport-","")+e;n.eventTrigger(this.sidebar,c)}else this._initialized&&(this.sidebarInner.style.left=s.inner.left);this.affixedType=i}}},{key:"_widthBreakpoint",value:function(){window.innerWidth<=this.options.minWidth?(this._breakpoint=!0,this.affixedType="STATIC",this.sidebar.removeAttribute("style"),n.removeClass(this.sidebar,this.options.stickyClass),this.sidebarInner.removeAttribute("style")):this._breakpoint=!1}},{key:"updateSticky",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this._running||(this._running=!0,function(e){requestAnimationFrame(function(){switch(e){case"scroll":t._calcDimensionsWithScroll(),t.observeScrollDir(),t.stickyPosition();break;case"resize":default:t._widthBreakpoint(),t.calcDimensions(),t.stickyPosition(!0)}t._running=!1})}(e.type))}},{key:"_setSupportFeatures",value:function(){var t=this.support;t.transform=n.supportTransform(),t.transform3d=n.supportTransform(!0)}},{key:"_getTranslate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return this.support.transform3d?"translate3d("+t+", "+e+", "+i+")":!!this.support.translate&&"translate("+t+", "+e+")"}},{key:"destroy",value:function(){window.removeEventListener("resize",this,{caption:!1}),window.removeEventListener("scroll",this,{caption:!1}),this.sidebar.classList.remove(this.options.stickyClass),this.sidebar.style.minHeight="",this.sidebar.removeEventListener("update"+e,this);var t={inner:{},outer:{}};t.inner={position:"",top:"",left:"",bottom:"",width:"",transform:""},t.outer={height:"",position:""};for(var i in t.outer)this.sidebar.style[i]=t.outer[i];for(var n in t.inner)this.sidebarInner.style[n]=t.inner[n];this.options.resizeSensor&&"undefined"!=typeof ResizeSensor&&(ResizeSensor.detach(this.sidebarInner,this.handleEvent),ResizeSensor.detach(this.container,this.handleEvent))}}],[{key:"supportTransform",value:function(t){var e=!1,i=t?"perspective":"transform",n=i.charAt(0).toUpperCase()+i.slice(1),s=document.createElement("support").style;return(i+" "+["Webkit","Moz","O","ms"].join(n+" ")+n).split(" ").forEach(function(t,i){if(void 0!==s[t])return e=t,!1}),e}},{key:"eventTrigger",value:function(t,e,i){try{n=new CustomEvent(e,{detail:i})}catch(t){var n;(n=document.createEvent("CustomEvent")).initCustomEvent(e,!0,!0,i)}t.dispatchEvent(n)}},{key:"extend",value:function(t,e){var i={};for(var n in t)void 0!==e[n]?i[n]=e[n]:i[n]=t[n];return i}},{key:"offsetRelative",value:function(t){var e={left:0,top:0};do{var i=t.offsetTop,n=t.offsetLeft;isNaN(i)||(e.top+=i),isNaN(n)||(e.left+=n),t="BODY"===t.tagName?t.parentElement:t.offsetParent}while(t);return e}},{key:"addClass",value:function(t,e){n.hasClass(t,e)||(t.classList?t.classList.add(e):t.className+=" "+e)}},{key:"removeClass",value:function(t,e){n.hasClass(t,e)&&(t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\b)"+e.split(" ").join("|")+"(\\b|$)","gi")," "))}},{key:"hasClass",value:function(t,e){return t.classList?t.classList.contains(e):new RegExp("(^| )"+e+"( |$)","gi").test(t.className)}}]),n}()}();return window.StickySidebar=e,e}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.StickySidebar={})}(this,function(t){"use strict";"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var e=function(t,e){return e={exports:{}},t(e,e.exports),e.exports}(function(t,e){!function(t,i){i(e)}(0,function(t){function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function t(t,e){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{};if(e(this,o),this.options=o.extend(n,s),this.sidebar="string"==typeof t?document.querySelector(t):t,void 0===this.sidebar)throw new Error("There is no specific sidebar element.");this.sidebarInner=!1,this.container=this.sidebar.parentElement,this.affixedType="STATIC",this.direction="down",this.support={transform:!1,transform3d:!1},this._initialized=!1,this._reStyle=!1,this._breakpoint=!1,this.dimensions={translateY:0,maxTranslateY:0,topSpacing:0,lastTopSpacing:0,bottomSpacing:0,lastBottomSpacing:0,sidebarHeight:0,sidebarWidth:0,containerTop:0,containerHeight:0,viewportHeight:0,viewportTop:0,lastViewportTop:0},["handleEvent"].forEach(function(t){i[t]=i[t].bind(i)}),this.initialize()}return i(o,[{key:"initialize",value:function(){var t=this;if(this._setSupportFeatures(),this.options.innerWrapperSelector&&(this.sidebarInner=this.sidebar.querySelector(this.options.innerWrapperSelector),null===this.sidebarInner&&(this.sidebarInner=!1)),!this.sidebarInner){var e=document.createElement("div");for(e.setAttribute("class","inner-wrapper-sticky"),this.sidebar.appendChild(e);this.sidebar.firstChild!=e;)e.appendChild(this.sidebar.firstChild);this.sidebarInner=this.sidebar.querySelector(".inner-wrapper-sticky")}if(this.options.containerSelector){var i=document.querySelectorAll(this.options.containerSelector);if((i=Array.prototype.slice.call(i)).forEach(function(e,i){e.contains(t.sidebar)&&(t.container=e)}),!i.length)throw new Error("The container does not contains on the sidebar.")}"function"!=typeof this.options.topSpacing&&(this.options.topSpacing=parseInt(this.options.topSpacing)||0),"function"!=typeof this.options.bottomSpacing&&(this.options.bottomSpacing=parseInt(this.options.bottomSpacing)||0),this._widthBreakpoint(),this.calcDimensions(),this.stickyPosition(),this.bindEvents(),this._initialized=!0}},{key:"bindEvents",value:function(){window.addEventListener("resize",this,{passive:!0,capture:!1}),window.addEventListener("scroll",this,{passive:!0,capture:!1}),this.sidebar.addEventListener("update"+t,this),this.options.resizeSensor&&"undefined"!=typeof ResizeSensor&&(new ResizeSensor(this.sidebarInner,this.handleEvent),new ResizeSensor(this.container,this.handleEvent))}},{key:"handleEvent",value:function(t){this.updateSticky(t)}},{key:"calcDimensions",value:function(){if(!this._breakpoint){var t=this.dimensions;t.containerTop=o.offsetRelative(this.container).top,t.containerHeight=this.container.clientHeight,t.containerBottom=t.containerTop+t.containerHeight,t.sidebarHeight=this.sidebarInner.offsetHeight,t.sidebarWidth=this.sidebarInner.offsetWidth,t.viewportHeight=window.innerHeight,t.maxTranslateY=t.containerHeight-t.sidebarHeight,this._calcDimensionsWithScroll()}}},{key:"_calcDimensionsWithScroll",value:function(){var t=this.dimensions;t.sidebarLeft=o.offsetRelative(this.sidebar).left,t.viewportTop=document.documentElement.scrollTop||document.body.scrollTop,t.viewportBottom=t.viewportTop+t.viewportHeight,t.viewportLeft=document.documentElement.scrollLeft||document.body.scrollLeft,t.topSpacing=this.options.topSpacing,t.bottomSpacing=this.options.bottomSpacing,"function"==typeof t.topSpacing&&(t.topSpacing=parseInt(t.topSpacing(this.sidebar))||0),"function"==typeof t.bottomSpacing&&(t.bottomSpacing=parseInt(t.bottomSpacing(this.sidebar))||0),"VIEWPORT-TOP"===this.affixedType?t.topSpacing=t.containerBottom?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):i>=t.containerTop&&(t.translateY=i-t.containerTop,o="VIEWPORT-TOP"):t.containerBottom<=n?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):e+t.translateY<=n?(t.translateY=n-e,o="VIEWPORT-BOTTOM"):t.containerTop+t.translateY<=i&&0!==t.translateY&&t.maxTranslateY!==t.translateY&&(o="VIEWPORT-UNBOTTOM"),o}},{key:"_getAffixTypeScrollingUp",value:function(){var t=this.dimensions,e=t.sidebarHeight+t.containerTop,i=t.viewportTop+t.topSpacing,n=t.viewportBottom-t.bottomSpacing,o=this.affixedType;return i<=t.translateY+t.containerTop?(t.translateY=i-t.containerTop,o="VIEWPORT-TOP"):t.containerBottom<=n?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):this.isSidebarFitsViewport()||t.containerTop<=i&&0!==t.translateY&&t.maxTranslateY!==t.translateY&&(o="VIEWPORT-UNBOTTOM"),o}},{key:"_getStyle",value:function(t){if(void 0!==t){var e={inner:{},outer:{}},i=this.dimensions;switch(t){case"VIEWPORT-TOP":e.inner={position:"fixed",top:i.topSpacing,left:i.sidebarLeft-i.viewportLeft,width:i.sidebarWidth};break;case"VIEWPORT-BOTTOM":e.inner={position:"fixed",top:"auto",left:i.sidebarLeft,bottom:i.bottomSpacing,width:i.sidebarWidth};break;case"CONTAINER-BOTTOM":case"VIEWPORT-UNBOTTOM":var n=this._getTranslate(0,i.translateY+"px");e.inner=n?{transform:n}:{position:"absolute",top:i.translateY,width:i.sidebarWidth}}switch(t){case"VIEWPORT-TOP":case"VIEWPORT-BOTTOM":case"VIEWPORT-UNBOTTOM":case"CONTAINER-BOTTOM":e.outer={height:i.sidebarHeight,position:"relative"}}return e.outer=o.extend({height:"",position:""},e.outer),e.inner=o.extend({position:"relative",top:"",left:"",bottom:"",width:"",transform:""},e.inner),e}}},{key:"stickyPosition",value:function(e){if(!this._breakpoint){e=this._reStyle||e||!1;var i=this.getAffixType(),n=this._getStyle(i);if((this.affixedType!=i||e)&&i){var s="affix."+i.toLowerCase().replace("viewport-","")+t;o.eventTrigger(this.sidebar,s),"STATIC"===i?o.removeClass(this.sidebar,this.options.stickyClass):o.addClass(this.sidebar,this.options.stickyClass);for(var r in n.outer){var a="number"==typeof n.outer[r]?"px":"";this.sidebar.style[r]=n.outer[r]+a}for(var p in n.inner){var c="number"==typeof n.inner[p]?"px":"";this.sidebarInner.style[p]=n.inner[p]+c}var l="affixed."+i.toLowerCase().replace("viewport-","")+t;o.eventTrigger(this.sidebar,l)}else this._initialized&&(this.sidebarInner.style.left=n.inner.left);this.affixedType=i}}},{key:"_widthBreakpoint",value:function(){window.innerWidth<=this.options.minWidth?(this._breakpoint=!0,this.affixedType="STATIC",this.sidebar.removeAttribute("style"),o.removeClass(this.sidebar,this.options.stickyClass),this.sidebarInner.removeAttribute("style")):this._breakpoint=!1}},{key:"updateSticky",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this._running||(this._running=!0,function(e){requestAnimationFrame(function(){switch(e){case"scroll":t._calcDimensionsWithScroll(),t.observeScrollDir(),t.stickyPosition();break;case"resize":default:t._widthBreakpoint(),t.calcDimensions(),t.stickyPosition(!0)}t._running=!1})}(e.type))}},{key:"_setSupportFeatures",value:function(){var t=this.support;t.transform=o.supportTransform(),t.transform3d=o.supportTransform(!0)}},{key:"_getTranslate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return this.support.transform3d?"translate3d("+t+", "+e+", "+i+")":!!this.support.translate&&"translate("+t+", "+e+")"}},{key:"destroy",value:function(){window.removeEventListener("resize",this,{capture:!1}),window.removeEventListener("scroll",this,{capture:!1}),this.sidebar.classList.remove(this.options.stickyClass),this.sidebar.style.minHeight="",this.sidebar.removeEventListener("update"+t,this);var e={inner:{},outer:{}};e.inner={position:"",top:"",left:"",bottom:"",width:"",transform:""},e.outer={height:"",position:""};for(var i in e.outer)this.sidebar.style[i]=e.outer[i];for(var n in e.inner)this.sidebarInner.style[n]=e.inner[n];this.options.resizeSensor&&"undefined"!=typeof ResizeSensor&&(ResizeSensor.detach(this.sidebarInner,this.handleEvent),ResizeSensor.detach(this.container,this.handleEvent))}}],[{key:"supportTransform",value:function(t){var e=!1,i=t?"perspective":"transform",n=i.charAt(0).toUpperCase()+i.slice(1),o=["Webkit","Moz","O","ms"],s=document.createElement("support").style;return(i+" "+o.join(n+" ")+n).split(" ").forEach(function(t,i){if(void 0!==s[t])return e=t,!1}),e}},{key:"eventTrigger",value:function(t,e,i){try{var n=new CustomEvent(e,{detail:i})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(e,!0,!0,i)}t.dispatchEvent(n)}},{key:"extend",value:function(t,e){var i={};for(var n in t)void 0!==e[n]?i[n]=e[n]:i[n]=t[n];return i}},{key:"offsetRelative",value:function(t){var e={left:0,top:0};do{var i=t.offsetTop,n=t.offsetLeft;isNaN(i)||(e.top+=i),isNaN(n)||(e.left+=n),t="BODY"===t.tagName?t.parentElement:t.offsetParent}while(t);return e}},{key:"addClass",value:function(t,e){o.hasClass(t,e)||(t.classList?t.classList.add(e):t.className+=" "+e)}},{key:"removeClass",value:function(t,e){o.hasClass(t,e)&&(t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\b)"+e.split(" ").join("|")+"(\\b|$)","gi")," "))}},{key:"hasClass",value:function(t,e){return t.classList?t.classList.contains(e):new RegExp("(^| )"+e+"( |$)","gi").test(t.className)}},{key:"defaults",get:function(){return n}}]),o}()}();t.default=n,window.StickySidebar=n})}),i=function(t){return t&&t.__esModule?t.default:t}(e);t.default=i,t.__moduleExports=e,Object.defineProperty(t,"__esModule",{value:!0})}); \ No newline at end of file From 38f4b1147af24844f8ad417ceddc734b6607ab5c Mon Sep 17 00:00:00 2001 From: Ahmed Date: Mon, 12 Mar 2018 12:34:36 +0200 Subject: [PATCH 2/4] Add test packages to devDependencies --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e5fd907..0ce42f2 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "babel-plugin-transform-export-extensions": "^6.22.0", "babel-preset-env": "^1.6.0", "babel-register": "^6.26.0", + "chai": "^4.1.2", "gulp": "^3.9.1", "gulp-babel": "^6.1.2", "gulp-header": "^1.8.9", @@ -57,6 +58,7 @@ "rollup-plugin-babel": "^3.0.2", "rollup-plugin-commonjs": "^8.2.1", "rollup-plugin-eslint": "^4.0.0", - "rollup-plugin-node-resolve": "^3.0.0" + "rollup-plugin-node-resolve": "^3.0.0", + "sinon": "^4.4.3" } } From 954fbbe87d1fa975252a2232e3001f04a7b16e0f Mon Sep 17 00:00:00 2001 From: Ahmed Date: Wed, 14 Mar 2018 16:50:30 +0200 Subject: [PATCH 3/4] Add top/bottom spacing in consideration to isSidebarFitsViewport method --- src/sticky-sidebar.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sticky-sidebar.js b/src/sticky-sidebar.js index 59852c2..67e7230 100644 --- a/src/sticky-sidebar.js +++ b/src/sticky-sidebar.js @@ -282,7 +282,9 @@ const StickySidebar = (() => { * @return {Boolean} */ isSidebarFitsViewport(){ - return this.dimensions.sidebarHeight < this.dimensions.viewportHeight; + let dims = this.dimensions; + let offset = this.scrollDirection === 'down' ? dims.lastBottomSpacing : dims.lastTopSpacing; + return this.dimensions.sidebarHeight + offset < this.dimensions.viewportHeight; } /** From bcd40bbf95e84b75916bc3535d7475447f9383f8 Mon Sep 17 00:00:00 2001 From: Ahmed Date: Wed, 14 Mar 2018 16:53:26 +0200 Subject: [PATCH 4/4] Re-build the bundle --- dist/jquery.sticky-sidebar.js | 15 ++++++++------- dist/jquery.sticky-sidebar.js.map | 2 +- dist/jquery.sticky-sidebar.min.js | 2 +- dist/sticky-sidebar.js | 13 ++++++++----- dist/sticky-sidebar.js.map | 2 +- dist/sticky-sidebar.min.js | 2 +- src/sticky-sidebar.js | 4 ++-- 7 files changed, 22 insertions(+), 18 deletions(-) diff --git a/dist/jquery.sticky-sidebar.js b/dist/jquery.sticky-sidebar.js index 2db7654..f60442b 100644 --- a/dist/jquery.sticky-sidebar.js +++ b/dist/jquery.sticky-sidebar.js @@ -9,7 +9,7 @@ var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== function unwrapExports (x) { - return x && x.__esModule ? x['default'] : x; + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function createCommonjsModule(fn, module) { @@ -24,8 +24,6 @@ var stickySidebar = createCommonjsModule(function (module, exports) { factory(exports); } })(commonjsGlobal, function (exports) { - 'use strict'; - Object.defineProperty(exports, "__esModule", { value: true }); @@ -56,7 +54,7 @@ var stickySidebar = createCommonjsModule(function (module, exports) { /** * Sticky Sidebar JavaScript Plugin. - * @version 3.3.1 + * @version 3.3.4 * @author Ahmed Bouhuolia * @license The MIT License (MIT) */ @@ -325,7 +323,9 @@ var stickySidebar = createCommonjsModule(function (module, exports) { }, { key: 'isSidebarFitsViewport', value: function isSidebarFitsViewport() { - return this.dimensions.sidebarHeight < this.dimensions.viewportHeight; + var dims = this.dimensions; + var offset = this.scrollDirection === 'down' ? dims.lastBottomSpacing : dims.lastTopSpacing; + return this.dimensions.sidebarHeight + offset < this.dimensions.viewportHeight; } }, { key: 'observeScrollDir', @@ -463,6 +463,9 @@ var stickySidebar = createCommonjsModule(function (module, exports) { force = this._reStyle || force || false; + var offsetTop = this.options.topSpacing; + var offsetBottom = this.options.bottomSpacing; + var affixType = this.getAffixType(); var style = this._getStyle(affixType); @@ -687,8 +690,6 @@ var jquery_stickySidebar = createCommonjsModule(function (module, exports) { factory(stickySidebar); } })(commonjsGlobal, function (_stickySidebar) { - 'use strict'; - var _stickySidebar2 = _interopRequireDefault(_stickySidebar); function _interopRequireDefault(obj) { diff --git a/dist/jquery.sticky-sidebar.js.map b/dist/jquery.sticky-sidebar.js.map index 80a10e7..a90bb21 100644 --- a/dist/jquery.sticky-sidebar.js.map +++ b/dist/jquery.sticky-sidebar.js.map @@ -1 +1 @@ -{"version":3,"file":"jquery.sticky-sidebar.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file +{"version":3,"file":"jquery.sticky-sidebar.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/dist/jquery.sticky-sidebar.min.js b/dist/jquery.sticky-sidebar.min.js index a0e0c2b..a83e472 100644 --- a/dist/jquery.sticky-sidebar.min.js +++ b/dist/jquery.sticky-sidebar.min.js @@ -5,4 +5,4 @@ * @author Ahmed Bouhuolia * @license The MIT License (MIT) **/ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.StickySidebar=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule?t.default:t}function e(t,e){return e={exports:{}},t(e,e.exports),e.exports}"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var i=e(function(t,e){!function(t,i){i(e)}(0,function(t){function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function t(t,e){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{};if(e(this,o),this.options=o.extend(n,s),this.sidebar="string"==typeof t?document.querySelector(t):t,void 0===this.sidebar)throw new Error("There is no specific sidebar element.");this.sidebarInner=!1,this.container=this.sidebar.parentElement,this.affixedType="STATIC",this.direction="down",this.support={transform:!1,transform3d:!1},this._initialized=!1,this._reStyle=!1,this._breakpoint=!1,this.dimensions={translateY:0,maxTranslateY:0,topSpacing:0,lastTopSpacing:0,bottomSpacing:0,lastBottomSpacing:0,sidebarHeight:0,sidebarWidth:0,containerTop:0,containerHeight:0,viewportHeight:0,viewportTop:0,lastViewportTop:0},["handleEvent"].forEach(function(t){i[t]=i[t].bind(i)}),this.initialize()}return i(o,[{key:"initialize",value:function(){var t=this;if(this._setSupportFeatures(),this.options.innerWrapperSelector&&(this.sidebarInner=this.sidebar.querySelector(this.options.innerWrapperSelector),null===this.sidebarInner&&(this.sidebarInner=!1)),!this.sidebarInner){var e=document.createElement("div");for(e.setAttribute("class","inner-wrapper-sticky"),this.sidebar.appendChild(e);this.sidebar.firstChild!=e;)e.appendChild(this.sidebar.firstChild);this.sidebarInner=this.sidebar.querySelector(".inner-wrapper-sticky")}if(this.options.containerSelector){var i=document.querySelectorAll(this.options.containerSelector);if((i=Array.prototype.slice.call(i)).forEach(function(e,i){e.contains(t.sidebar)&&(t.container=e)}),!i.length)throw new Error("The container does not contains on the sidebar.")}"function"!=typeof this.options.topSpacing&&(this.options.topSpacing=parseInt(this.options.topSpacing)||0),"function"!=typeof this.options.bottomSpacing&&(this.options.bottomSpacing=parseInt(this.options.bottomSpacing)||0),this._widthBreakpoint(),this.calcDimensions(),this.stickyPosition(),this.bindEvents(),this._initialized=!0}},{key:"bindEvents",value:function(){window.addEventListener("resize",this,{passive:!0,capture:!1}),window.addEventListener("scroll",this,{passive:!0,capture:!1}),this.sidebar.addEventListener("update"+t,this),this.options.resizeSensor&&"undefined"!=typeof ResizeSensor&&(new ResizeSensor(this.sidebarInner,this.handleEvent),new ResizeSensor(this.container,this.handleEvent))}},{key:"handleEvent",value:function(t){this.updateSticky(t)}},{key:"calcDimensions",value:function(){if(!this._breakpoint){var t=this.dimensions;t.containerTop=o.offsetRelative(this.container).top,t.containerHeight=this.container.clientHeight,t.containerBottom=t.containerTop+t.containerHeight,t.sidebarHeight=this.sidebarInner.offsetHeight,t.sidebarWidth=this.sidebarInner.offsetWidth,t.viewportHeight=window.innerHeight,t.maxTranslateY=t.containerHeight-t.sidebarHeight,this._calcDimensionsWithScroll()}}},{key:"_calcDimensionsWithScroll",value:function(){var t=this.dimensions;t.sidebarLeft=o.offsetRelative(this.sidebar).left,t.viewportTop=document.documentElement.scrollTop||document.body.scrollTop,t.viewportBottom=t.viewportTop+t.viewportHeight,t.viewportLeft=document.documentElement.scrollLeft||document.body.scrollLeft,t.topSpacing=this.options.topSpacing,t.bottomSpacing=this.options.bottomSpacing,"function"==typeof t.topSpacing&&(t.topSpacing=parseInt(t.topSpacing(this.sidebar))||0),"function"==typeof t.bottomSpacing&&(t.bottomSpacing=parseInt(t.bottomSpacing(this.sidebar))||0),"VIEWPORT-TOP"===this.affixedType?t.topSpacing=t.containerBottom?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):i>=t.containerTop&&(t.translateY=i-t.containerTop,o="VIEWPORT-TOP"):t.containerBottom<=n?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):e+t.translateY<=n?(t.translateY=n-e,o="VIEWPORT-BOTTOM"):t.containerTop+t.translateY<=i&&0!==t.translateY&&t.maxTranslateY!==t.translateY&&(o="VIEWPORT-UNBOTTOM"),o}},{key:"_getAffixTypeScrollingUp",value:function(){var t=this.dimensions,e=t.sidebarHeight+t.containerTop,i=t.viewportTop+t.topSpacing,n=t.viewportBottom-t.bottomSpacing,o=this.affixedType;return i<=t.translateY+t.containerTop?(t.translateY=i-t.containerTop,o="VIEWPORT-TOP"):t.containerBottom<=n?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):this.isSidebarFitsViewport()||t.containerTop<=i&&0!==t.translateY&&t.maxTranslateY!==t.translateY&&(o="VIEWPORT-UNBOTTOM"),o}},{key:"_getStyle",value:function(t){if(void 0!==t){var e={inner:{},outer:{}},i=this.dimensions;switch(t){case"VIEWPORT-TOP":e.inner={position:"fixed",top:i.topSpacing,left:i.sidebarLeft-i.viewportLeft,width:i.sidebarWidth};break;case"VIEWPORT-BOTTOM":e.inner={position:"fixed",top:"auto",left:i.sidebarLeft,bottom:i.bottomSpacing,width:i.sidebarWidth};break;case"CONTAINER-BOTTOM":case"VIEWPORT-UNBOTTOM":var n=this._getTranslate(0,i.translateY+"px");e.inner=n?{transform:n}:{position:"absolute",top:i.translateY,width:i.sidebarWidth}}switch(t){case"VIEWPORT-TOP":case"VIEWPORT-BOTTOM":case"VIEWPORT-UNBOTTOM":case"CONTAINER-BOTTOM":e.outer={height:i.sidebarHeight,position:"relative"}}return e.outer=o.extend({height:"",position:""},e.outer),e.inner=o.extend({position:"relative",top:"",left:"",bottom:"",width:"",transform:""},e.inner),e}}},{key:"stickyPosition",value:function(e){if(!this._breakpoint){e=this._reStyle||e||!1;var i=this.getAffixType(),n=this._getStyle(i);if((this.affixedType!=i||e)&&i){var s="affix."+i.toLowerCase().replace("viewport-","")+t;o.eventTrigger(this.sidebar,s),"STATIC"===i?o.removeClass(this.sidebar,this.options.stickyClass):o.addClass(this.sidebar,this.options.stickyClass);for(var r in n.outer){var a="number"==typeof n.outer[r]?"px":"";this.sidebar.style[r]=n.outer[r]+a}for(var p in n.inner){var c="number"==typeof n.inner[p]?"px":"";this.sidebarInner.style[p]=n.inner[p]+c}var l="affixed."+i.toLowerCase().replace("viewport-","")+t;o.eventTrigger(this.sidebar,l)}else this._initialized&&(this.sidebarInner.style.left=n.inner.left);this.affixedType=i}}},{key:"_widthBreakpoint",value:function(){window.innerWidth<=this.options.minWidth?(this._breakpoint=!0,this.affixedType="STATIC",this.sidebar.removeAttribute("style"),o.removeClass(this.sidebar,this.options.stickyClass),this.sidebarInner.removeAttribute("style")):this._breakpoint=!1}},{key:"updateSticky",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this._running||(this._running=!0,function(e){requestAnimationFrame(function(){switch(e){case"scroll":t._calcDimensionsWithScroll(),t.observeScrollDir(),t.stickyPosition();break;case"resize":default:t._widthBreakpoint(),t.calcDimensions(),t.stickyPosition(!0)}t._running=!1})}(e.type))}},{key:"_setSupportFeatures",value:function(){var t=this.support;t.transform=o.supportTransform(),t.transform3d=o.supportTransform(!0)}},{key:"_getTranslate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return this.support.transform3d?"translate3d("+t+", "+e+", "+i+")":!!this.support.translate&&"translate("+t+", "+e+")"}},{key:"destroy",value:function(){window.removeEventListener("resize",this,{capture:!1}),window.removeEventListener("scroll",this,{capture:!1}),this.sidebar.classList.remove(this.options.stickyClass),this.sidebar.style.minHeight="",this.sidebar.removeEventListener("update"+t,this);var e={inner:{},outer:{}};e.inner={position:"",top:"",left:"",bottom:"",width:"",transform:""},e.outer={height:"",position:""};for(var i in e.outer)this.sidebar.style[i]=e.outer[i];for(var n in e.inner)this.sidebarInner.style[n]=e.inner[n];this.options.resizeSensor&&"undefined"!=typeof ResizeSensor&&(ResizeSensor.detach(this.sidebarInner,this.handleEvent),ResizeSensor.detach(this.container,this.handleEvent))}}],[{key:"supportTransform",value:function(t){var e=!1,i=t?"perspective":"transform",n=i.charAt(0).toUpperCase()+i.slice(1),o=["Webkit","Moz","O","ms"],s=document.createElement("support").style;return(i+" "+o.join(n+" ")+n).split(" ").forEach(function(t,i){if(void 0!==s[t])return e=t,!1}),e}},{key:"eventTrigger",value:function(t,e,i){try{var n=new CustomEvent(e,{detail:i})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(e,!0,!0,i)}t.dispatchEvent(n)}},{key:"extend",value:function(t,e){var i={};for(var n in t)void 0!==e[n]?i[n]=e[n]:i[n]=t[n];return i}},{key:"offsetRelative",value:function(t){var e={left:0,top:0};do{var i=t.offsetTop,n=t.offsetLeft;isNaN(i)||(e.top+=i),isNaN(n)||(e.left+=n),t="BODY"===t.tagName?t.parentElement:t.offsetParent}while(t);return e}},{key:"addClass",value:function(t,e){o.hasClass(t,e)||(t.classList?t.classList.add(e):t.className+=" "+e)}},{key:"removeClass",value:function(t,e){o.hasClass(t,e)&&(t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\b)"+e.split(" ").join("|")+"(\\b|$)","gi")," "))}},{key:"hasClass",value:function(t,e){return t.classList?t.classList.contains(e):new RegExp("(^| )"+e+"( |$)","gi").test(t.className)}},{key:"defaults",get:function(){return n}}]),o}()}();t.default=n,window.StickySidebar=n})});return t(i),t(e(function(t,e){!function(t,e){e(i)}(0,function(t){var e=function(t){return t&&t.__esModule?t:{default:t}}(t);!function(){if("undefined"!=typeof window){var t=window.$||window.jQuery||window.Zepto;if(t){t.fn.stickySidebar=function(i){return this.each(function(){var n=t(this),o=t(this).data("stickySidebar");if(o||(o=new e.default(this,"object"==typeof i&&i),n.data("stickySidebar",o)),"string"==typeof i){if(void 0===o[i]&&-1===["destroy","updateSticky"].indexOf(i))throw new Error('No method named "'+i+'"');o[i]()}})},t.fn.stickySidebar.Constructor=e.default;var i=t.fn.stickySidebar;t.fn.stickySidebar.noConflict=function(){return t.fn.stickySidebar=i,this}}}}()})}))}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.StickySidebar=e()}(this,function(){"use strict";"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}function e(t,e){return t(e={exports:{}},e.exports),e.exports}var i=e(function(t,e){(function(t){Object.defineProperty(t,"__esModule",{value:!0});var l,n,e=function(){function n(t,e){for(var i=0;i=t.containerBottom?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):i>=t.containerTop&&(t.translateY=i-t.containerTop,o="VIEWPORT-TOP"):t.containerBottom<=n?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):e+t.translateY<=n?(t.translateY=n-e,o="VIEWPORT-BOTTOM"):t.containerTop+t.translateY<=i&&0!==t.translateY&&t.maxTranslateY!==t.translateY&&(o="VIEWPORT-UNBOTTOM"),o}},{key:"_getAffixTypeScrollingUp",value:function(){var t=this.dimensions,e=t.sidebarHeight+t.containerTop,i=t.viewportTop+t.topSpacing,n=t.viewportBottom-t.bottomSpacing,o=this.affixedType;return i<=t.translateY+t.containerTop?(t.translateY=i-t.containerTop,o="VIEWPORT-TOP"):t.containerBottom<=n?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):this.isSidebarFitsViewport()||t.containerTop<=i&&0!==t.translateY&&t.maxTranslateY!==t.translateY&&(o="VIEWPORT-UNBOTTOM"),o}},{key:"_getStyle",value:function(t){if(void 0!==t){var e={inner:{},outer:{}},i=this.dimensions;switch(t){case"VIEWPORT-TOP":e.inner={position:"fixed",top:i.topSpacing,left:i.sidebarLeft-i.viewportLeft,width:i.sidebarWidth};break;case"VIEWPORT-BOTTOM":e.inner={position:"fixed",top:"auto",left:i.sidebarLeft,bottom:i.bottomSpacing,width:i.sidebarWidth};break;case"CONTAINER-BOTTOM":case"VIEWPORT-UNBOTTOM":var n=this._getTranslate(0,i.translateY+"px");e.inner=n?{transform:n}:{position:"absolute",top:i.translateY,width:i.sidebarWidth}}switch(t){case"VIEWPORT-TOP":case"VIEWPORT-BOTTOM":case"VIEWPORT-UNBOTTOM":case"CONTAINER-BOTTOM":e.outer={height:i.sidebarHeight,position:"relative"}}return e.outer=c.extend({height:"",position:""},e.outer),e.inner=c.extend({position:"relative",top:"",left:"",bottom:"",width:"",transform:""},e.inner),e}}},{key:"stickyPosition",value:function(t){if(!this._breakpoint){t=this._reStyle||t||!1,this.options.topSpacing,this.options.bottomSpacing;var e=this.getAffixType(),i=this._getStyle(e);if((this.affixedType!=e||t)&&e){var n="affix."+e.toLowerCase().replace("viewport-","")+l;for(var o in c.eventTrigger(this.sidebar,n),"STATIC"===e?c.removeClass(this.sidebar,this.options.stickyClass):c.addClass(this.sidebar,this.options.stickyClass),i.outer){var s="number"==typeof i.outer[o]?"px":"";this.sidebar.style[o]=i.outer[o]+s}for(var r in i.inner){var a="number"==typeof i.inner[r]?"px":"";this.sidebarInner.style[r]=i.inner[r]+a}var p="affixed."+e.toLowerCase().replace("viewport-","")+l;c.eventTrigger(this.sidebar,p)}else this._initialized&&(this.sidebarInner.style.left=i.inner.left);this.affixedType=e}}},{key:"_widthBreakpoint",value:function(){window.innerWidth<=this.options.minWidth?(this._breakpoint=!0,this.affixedType="STATIC",this.sidebar.removeAttribute("style"),c.removeClass(this.sidebar,this.options.stickyClass),this.sidebarInner.removeAttribute("style")):this._breakpoint=!1}},{key:"updateSticky",value:function(){var t,e=this,i=0 * @license The MIT License (MIT) */ @@ -325,7 +323,9 @@ var stickySidebar = createCommonjsModule(function (module, exports) { }, { key: 'isSidebarFitsViewport', value: function isSidebarFitsViewport() { - return this.dimensions.sidebarHeight < this.dimensions.viewportHeight; + var dims = this.dimensions; + var offset = this.scrollDirection === 'down' ? dims.lastBottomSpacing : dims.lastTopSpacing; + return this.dimensions.sidebarHeight + offset < this.dimensions.viewportHeight; } }, { key: 'observeScrollDir', @@ -463,6 +463,9 @@ var stickySidebar = createCommonjsModule(function (module, exports) { force = this._reStyle || force || false; + var offsetTop = this.options.topSpacing; + var offsetBottom = this.options.bottomSpacing; + var affixType = this.getAffixType(); var style = this._getStyle(affixType); diff --git a/dist/sticky-sidebar.js.map b/dist/sticky-sidebar.js.map index 7fa344f..a73d5cd 100644 --- a/dist/sticky-sidebar.js.map +++ b/dist/sticky-sidebar.js.map @@ -1 +1 @@ -{"version":3,"file":"sticky-sidebar.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file +{"version":3,"file":"sticky-sidebar.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/dist/sticky-sidebar.min.js b/dist/sticky-sidebar.min.js index 40f581b..1462f11 100644 --- a/dist/sticky-sidebar.min.js +++ b/dist/sticky-sidebar.min.js @@ -5,4 +5,4 @@ * @author Ahmed Bouhuolia * @license The MIT License (MIT) **/ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.StickySidebar={})}(this,function(t){"use strict";"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var e=function(t,e){return e={exports:{}},t(e,e.exports),e.exports}(function(t,e){!function(t,i){i(e)}(0,function(t){function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function t(t,e){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{};if(e(this,o),this.options=o.extend(n,s),this.sidebar="string"==typeof t?document.querySelector(t):t,void 0===this.sidebar)throw new Error("There is no specific sidebar element.");this.sidebarInner=!1,this.container=this.sidebar.parentElement,this.affixedType="STATIC",this.direction="down",this.support={transform:!1,transform3d:!1},this._initialized=!1,this._reStyle=!1,this._breakpoint=!1,this.dimensions={translateY:0,maxTranslateY:0,topSpacing:0,lastTopSpacing:0,bottomSpacing:0,lastBottomSpacing:0,sidebarHeight:0,sidebarWidth:0,containerTop:0,containerHeight:0,viewportHeight:0,viewportTop:0,lastViewportTop:0},["handleEvent"].forEach(function(t){i[t]=i[t].bind(i)}),this.initialize()}return i(o,[{key:"initialize",value:function(){var t=this;if(this._setSupportFeatures(),this.options.innerWrapperSelector&&(this.sidebarInner=this.sidebar.querySelector(this.options.innerWrapperSelector),null===this.sidebarInner&&(this.sidebarInner=!1)),!this.sidebarInner){var e=document.createElement("div");for(e.setAttribute("class","inner-wrapper-sticky"),this.sidebar.appendChild(e);this.sidebar.firstChild!=e;)e.appendChild(this.sidebar.firstChild);this.sidebarInner=this.sidebar.querySelector(".inner-wrapper-sticky")}if(this.options.containerSelector){var i=document.querySelectorAll(this.options.containerSelector);if((i=Array.prototype.slice.call(i)).forEach(function(e,i){e.contains(t.sidebar)&&(t.container=e)}),!i.length)throw new Error("The container does not contains on the sidebar.")}"function"!=typeof this.options.topSpacing&&(this.options.topSpacing=parseInt(this.options.topSpacing)||0),"function"!=typeof this.options.bottomSpacing&&(this.options.bottomSpacing=parseInt(this.options.bottomSpacing)||0),this._widthBreakpoint(),this.calcDimensions(),this.stickyPosition(),this.bindEvents(),this._initialized=!0}},{key:"bindEvents",value:function(){window.addEventListener("resize",this,{passive:!0,capture:!1}),window.addEventListener("scroll",this,{passive:!0,capture:!1}),this.sidebar.addEventListener("update"+t,this),this.options.resizeSensor&&"undefined"!=typeof ResizeSensor&&(new ResizeSensor(this.sidebarInner,this.handleEvent),new ResizeSensor(this.container,this.handleEvent))}},{key:"handleEvent",value:function(t){this.updateSticky(t)}},{key:"calcDimensions",value:function(){if(!this._breakpoint){var t=this.dimensions;t.containerTop=o.offsetRelative(this.container).top,t.containerHeight=this.container.clientHeight,t.containerBottom=t.containerTop+t.containerHeight,t.sidebarHeight=this.sidebarInner.offsetHeight,t.sidebarWidth=this.sidebarInner.offsetWidth,t.viewportHeight=window.innerHeight,t.maxTranslateY=t.containerHeight-t.sidebarHeight,this._calcDimensionsWithScroll()}}},{key:"_calcDimensionsWithScroll",value:function(){var t=this.dimensions;t.sidebarLeft=o.offsetRelative(this.sidebar).left,t.viewportTop=document.documentElement.scrollTop||document.body.scrollTop,t.viewportBottom=t.viewportTop+t.viewportHeight,t.viewportLeft=document.documentElement.scrollLeft||document.body.scrollLeft,t.topSpacing=this.options.topSpacing,t.bottomSpacing=this.options.bottomSpacing,"function"==typeof t.topSpacing&&(t.topSpacing=parseInt(t.topSpacing(this.sidebar))||0),"function"==typeof t.bottomSpacing&&(t.bottomSpacing=parseInt(t.bottomSpacing(this.sidebar))||0),"VIEWPORT-TOP"===this.affixedType?t.topSpacing=t.containerBottom?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):i>=t.containerTop&&(t.translateY=i-t.containerTop,o="VIEWPORT-TOP"):t.containerBottom<=n?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):e+t.translateY<=n?(t.translateY=n-e,o="VIEWPORT-BOTTOM"):t.containerTop+t.translateY<=i&&0!==t.translateY&&t.maxTranslateY!==t.translateY&&(o="VIEWPORT-UNBOTTOM"),o}},{key:"_getAffixTypeScrollingUp",value:function(){var t=this.dimensions,e=t.sidebarHeight+t.containerTop,i=t.viewportTop+t.topSpacing,n=t.viewportBottom-t.bottomSpacing,o=this.affixedType;return i<=t.translateY+t.containerTop?(t.translateY=i-t.containerTop,o="VIEWPORT-TOP"):t.containerBottom<=n?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):this.isSidebarFitsViewport()||t.containerTop<=i&&0!==t.translateY&&t.maxTranslateY!==t.translateY&&(o="VIEWPORT-UNBOTTOM"),o}},{key:"_getStyle",value:function(t){if(void 0!==t){var e={inner:{},outer:{}},i=this.dimensions;switch(t){case"VIEWPORT-TOP":e.inner={position:"fixed",top:i.topSpacing,left:i.sidebarLeft-i.viewportLeft,width:i.sidebarWidth};break;case"VIEWPORT-BOTTOM":e.inner={position:"fixed",top:"auto",left:i.sidebarLeft,bottom:i.bottomSpacing,width:i.sidebarWidth};break;case"CONTAINER-BOTTOM":case"VIEWPORT-UNBOTTOM":var n=this._getTranslate(0,i.translateY+"px");e.inner=n?{transform:n}:{position:"absolute",top:i.translateY,width:i.sidebarWidth}}switch(t){case"VIEWPORT-TOP":case"VIEWPORT-BOTTOM":case"VIEWPORT-UNBOTTOM":case"CONTAINER-BOTTOM":e.outer={height:i.sidebarHeight,position:"relative"}}return e.outer=o.extend({height:"",position:""},e.outer),e.inner=o.extend({position:"relative",top:"",left:"",bottom:"",width:"",transform:""},e.inner),e}}},{key:"stickyPosition",value:function(e){if(!this._breakpoint){e=this._reStyle||e||!1;var i=this.getAffixType(),n=this._getStyle(i);if((this.affixedType!=i||e)&&i){var s="affix."+i.toLowerCase().replace("viewport-","")+t;o.eventTrigger(this.sidebar,s),"STATIC"===i?o.removeClass(this.sidebar,this.options.stickyClass):o.addClass(this.sidebar,this.options.stickyClass);for(var r in n.outer){var a="number"==typeof n.outer[r]?"px":"";this.sidebar.style[r]=n.outer[r]+a}for(var p in n.inner){var c="number"==typeof n.inner[p]?"px":"";this.sidebarInner.style[p]=n.inner[p]+c}var l="affixed."+i.toLowerCase().replace("viewport-","")+t;o.eventTrigger(this.sidebar,l)}else this._initialized&&(this.sidebarInner.style.left=n.inner.left);this.affixedType=i}}},{key:"_widthBreakpoint",value:function(){window.innerWidth<=this.options.minWidth?(this._breakpoint=!0,this.affixedType="STATIC",this.sidebar.removeAttribute("style"),o.removeClass(this.sidebar,this.options.stickyClass),this.sidebarInner.removeAttribute("style")):this._breakpoint=!1}},{key:"updateSticky",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this._running||(this._running=!0,function(e){requestAnimationFrame(function(){switch(e){case"scroll":t._calcDimensionsWithScroll(),t.observeScrollDir(),t.stickyPosition();break;case"resize":default:t._widthBreakpoint(),t.calcDimensions(),t.stickyPosition(!0)}t._running=!1})}(e.type))}},{key:"_setSupportFeatures",value:function(){var t=this.support;t.transform=o.supportTransform(),t.transform3d=o.supportTransform(!0)}},{key:"_getTranslate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return this.support.transform3d?"translate3d("+t+", "+e+", "+i+")":!!this.support.translate&&"translate("+t+", "+e+")"}},{key:"destroy",value:function(){window.removeEventListener("resize",this,{capture:!1}),window.removeEventListener("scroll",this,{capture:!1}),this.sidebar.classList.remove(this.options.stickyClass),this.sidebar.style.minHeight="",this.sidebar.removeEventListener("update"+t,this);var e={inner:{},outer:{}};e.inner={position:"",top:"",left:"",bottom:"",width:"",transform:""},e.outer={height:"",position:""};for(var i in e.outer)this.sidebar.style[i]=e.outer[i];for(var n in e.inner)this.sidebarInner.style[n]=e.inner[n];this.options.resizeSensor&&"undefined"!=typeof ResizeSensor&&(ResizeSensor.detach(this.sidebarInner,this.handleEvent),ResizeSensor.detach(this.container,this.handleEvent))}}],[{key:"supportTransform",value:function(t){var e=!1,i=t?"perspective":"transform",n=i.charAt(0).toUpperCase()+i.slice(1),o=["Webkit","Moz","O","ms"],s=document.createElement("support").style;return(i+" "+o.join(n+" ")+n).split(" ").forEach(function(t,i){if(void 0!==s[t])return e=t,!1}),e}},{key:"eventTrigger",value:function(t,e,i){try{var n=new CustomEvent(e,{detail:i})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(e,!0,!0,i)}t.dispatchEvent(n)}},{key:"extend",value:function(t,e){var i={};for(var n in t)void 0!==e[n]?i[n]=e[n]:i[n]=t[n];return i}},{key:"offsetRelative",value:function(t){var e={left:0,top:0};do{var i=t.offsetTop,n=t.offsetLeft;isNaN(i)||(e.top+=i),isNaN(n)||(e.left+=n),t="BODY"===t.tagName?t.parentElement:t.offsetParent}while(t);return e}},{key:"addClass",value:function(t,e){o.hasClass(t,e)||(t.classList?t.classList.add(e):t.className+=" "+e)}},{key:"removeClass",value:function(t,e){o.hasClass(t,e)&&(t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\b)"+e.split(" ").join("|")+"(\\b|$)","gi")," "))}},{key:"hasClass",value:function(t,e){return t.classList?t.classList.contains(e):new RegExp("(^| )"+e+"( |$)","gi").test(t.className)}},{key:"defaults",get:function(){return n}}]),o}()}();t.default=n,window.StickySidebar=n})}),i=function(t){return t&&t.__esModule?t.default:t}(e);t.default=i,t.__moduleExports=e,Object.defineProperty(t,"__esModule",{value:!0})}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.StickySidebar={})}(this,function(t){"use strict";"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var e,i,n=(function(t,e){(function(t){Object.defineProperty(t,"__esModule",{value:!0});var l,n,e=function(){function n(t,e){for(var i=0;i=t.containerBottom?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):i>=t.containerTop&&(t.translateY=i-t.containerTop,o="VIEWPORT-TOP"):t.containerBottom<=n?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):e+t.translateY<=n?(t.translateY=n-e,o="VIEWPORT-BOTTOM"):t.containerTop+t.translateY<=i&&0!==t.translateY&&t.maxTranslateY!==t.translateY&&(o="VIEWPORT-UNBOTTOM"),o}},{key:"_getAffixTypeScrollingUp",value:function(){var t=this.dimensions,e=t.sidebarHeight+t.containerTop,i=t.viewportTop+t.topSpacing,n=t.viewportBottom-t.bottomSpacing,o=this.affixedType;return i<=t.translateY+t.containerTop?(t.translateY=i-t.containerTop,o="VIEWPORT-TOP"):t.containerBottom<=n?(t.translateY=t.containerBottom-e,o="CONTAINER-BOTTOM"):this.isSidebarFitsViewport()||t.containerTop<=i&&0!==t.translateY&&t.maxTranslateY!==t.translateY&&(o="VIEWPORT-UNBOTTOM"),o}},{key:"_getStyle",value:function(t){if(void 0!==t){var e={inner:{},outer:{}},i=this.dimensions;switch(t){case"VIEWPORT-TOP":e.inner={position:"fixed",top:i.topSpacing,left:i.sidebarLeft-i.viewportLeft,width:i.sidebarWidth};break;case"VIEWPORT-BOTTOM":e.inner={position:"fixed",top:"auto",left:i.sidebarLeft,bottom:i.bottomSpacing,width:i.sidebarWidth};break;case"CONTAINER-BOTTOM":case"VIEWPORT-UNBOTTOM":var n=this._getTranslate(0,i.translateY+"px");e.inner=n?{transform:n}:{position:"absolute",top:i.translateY,width:i.sidebarWidth}}switch(t){case"VIEWPORT-TOP":case"VIEWPORT-BOTTOM":case"VIEWPORT-UNBOTTOM":case"CONTAINER-BOTTOM":e.outer={height:i.sidebarHeight,position:"relative"}}return e.outer=c.extend({height:"",position:""},e.outer),e.inner=c.extend({position:"relative",top:"",left:"",bottom:"",width:"",transform:""},e.inner),e}}},{key:"stickyPosition",value:function(t){if(!this._breakpoint){t=this._reStyle||t||!1,this.options.topSpacing,this.options.bottomSpacing;var e=this.getAffixType(),i=this._getStyle(e);if((this.affixedType!=e||t)&&e){var n="affix."+e.toLowerCase().replace("viewport-","")+l;for(var o in c.eventTrigger(this.sidebar,n),"STATIC"===e?c.removeClass(this.sidebar,this.options.stickyClass):c.addClass(this.sidebar,this.options.stickyClass),i.outer){var s="number"==typeof i.outer[o]?"px":"";this.sidebar.style[o]=i.outer[o]+s}for(var r in i.inner){var a="number"==typeof i.inner[r]?"px":"";this.sidebarInner.style[r]=i.inner[r]+a}var p="affixed."+e.toLowerCase().replace("viewport-","")+l;c.eventTrigger(this.sidebar,p)}else this._initialized&&(this.sidebarInner.style.left=i.inner.left);this.affixedType=e}}},{key:"_widthBreakpoint",value:function(){window.innerWidth<=this.options.minWidth?(this._breakpoint=!0,this.affixedType="STATIC",this.sidebar.removeAttribute("style"),c.removeClass(this.sidebar,this.options.stickyClass),this.sidebarInner.removeAttribute("style")):this._breakpoint=!1}},{key:"updateSticky",value:function(){var t,e=this,i=0 * @license The MIT License (MIT) */ @@ -11,7 +11,7 @@ const StickySidebar = (() => { // --------------------------------- // const EVENT_KEY = '.stickySidebar'; - const VERSION = '3.3.3'; + const VERSION = '3.3.4'; const DEFAULTS = { /**