diff --git a/js/theia-sticky-sidebar.js b/js/theia-sticky-sidebar.js index 658c1a1..410ce5b 100755 --- a/js/theia-sticky-sidebar.js +++ b/js/theia-sticky-sidebar.js @@ -8,364 +8,385 @@ * Released under the MIT license */ -(function ($) { - $.fn.theiaStickySidebar = function (options) { - var defaults = { - 'containerSelector': '', - 'additionalMarginTop': 0, - 'additionalMarginBottom': 0, - 'updateSidebarHeight': true, - 'minWidth': 0, - 'disableOnResponsiveLayouts': true, - 'sidebarBehavior': 'modern', - 'defaultPosition': 'relative', - 'namespace': 'TSS' - }; - options = $.extend(defaults, options); - - // Validate options - options.additionalMarginTop = parseInt(options.additionalMarginTop) || 0; - options.additionalMarginBottom = parseInt(options.additionalMarginBottom) || 0; - - tryInitOrHookIntoEvents(options, this); - - // Try doing init, otherwise hook into window.resize and document.scroll and try again then. - function tryInitOrHookIntoEvents(options, $that) { - var success = tryInit(options, $that); - - if (!success) { - console.log('TSS: Body width smaller than options.minWidth. Init is delayed.'); - - $(document).on('scroll.' + options.namespace, function (options, $that) { - return function (evt) { - var success = tryInit(options, $that); - - if (success) { - $(this).unbind(evt); - } - }; - }(options, $that)); - $(window).on('resize.' + options.namespace, function (options, $that) { - return function (evt) { - var success = tryInit(options, $that); +import resizeSensor from 'resize-sensor'; +import {theiaEventHandler} from './theiaEventHandler' + +const theiaStickySidebar = (target, options) => { + const defaults = { + 'containerSelector': '', + 'additionalMarginTop': 0, + 'additionalMarginBottom': 0, + 'updateSidebarHeight': true, + 'minWidth': 0, + 'disableOnResponsiveLayouts': true, + 'sidebarBehavior': 'modern', + 'defaultPosition': 'relative', + 'namespace': 'TSS' + }; + options = Object.assign(defaults, options); + + // Validate options + options.additionalMarginTop = parseInt(options.additionalMarginTop) || 0; + options.additionalMarginBottom = parseInt(options.additionalMarginBottom) || 0; + + tryInitOrHookIntoEvents(options, target); + + // Try doing init, otherwise hook into window.resize and document.scroll and try again then. + function tryInitOrHookIntoEvents(options, $that) { + const success = tryInit(options, $that); + + if (!success) { + console.log('TSS: Body width smaller than options.minWidth. Init is delayed.'); + + theiaEventHandler.addEventListener(document, 'scroll.' + options.namespace, function (options, $that) { + return function () { + const success = tryInit(options, $that); + + if (success) { + theiaEventHandler.removeEventListener(document, 'scroll.' + options.namespace); + } + }; + }(options, $that)); + theiaEventHandler.addEventListener(window, 'resize.' + options.namespace, function (options, $that) { + return function () { + const success = tryInit(options, $that); - if (success) { - $(this).unbind(evt); - } - }; - }(options, $that)) - } + if (success) { + theiaEventHandler.removeEventListener(window, 'resize.' + options.namespace); + } + }; + }(options, $that)) } + } - // Try doing init if proper conditions are met. - function tryInit(options, $that) { - if (options.initialized === true) { - return true; - } + // Try doing init if proper conditions are met. + function tryInit(options, $that) { + if (options.initialized === true) { + return true; + } - if ($('body').width() < options.minWidth) { - return false; - } + if (document.querySelector('body').getBoundingClientRect().width < options.minWidth) { + return false; + } - init(options, $that); + init(options, $that); - return true; + return true; + } + + // Init the sticky sidebar(s). + function init(options, $that) { + options.initialized = true; + + // Add CSS + const existingStylesheet = document.querySelectorAll('#theia-sticky-sidebar-stylesheet-' + options.namespace); + + if (existingStylesheet.length === 0) { + document.querySelector('head').insertAdjacentHTML( + "beforeend", ''); } - // Init the sticky sidebar(s). - function init(options, $that) { - options.initialized = true; + $that.forEach(function (element) { + const o = {}; - // Add CSS - var existingStylesheet = $('#theia-sticky-sidebar-stylesheet-' + options.namespace); - if (existingStylesheet.length === 0) { - $('head').append($('')); - } + o.sidebar = element; - $that.each(function () { - var o = {}; + // Save options + o.options = options || {}; - o.sidebar = $(this); + // Get container + o.container = o.options.containerSelector === '' ? [] : document.querySelectorAll(o.options.containerSelector); + if (o.container.length === 0) { + o.container = o.sidebar.parentNode; + } - // Save options - o.options = options || {}; + // Create sticky sidebar + let parentNode = o.sidebar.parentNode; + while (parentNode && parentNode !== document) { + parentNode.style.setProperty('-webkit-transform', 'none'); // Fix for WebKit bug - https://code.google.com/p/chromium/issues/detail?id=20574 + parentNode = parentNode.parentNode; + } - // Get container - o.container = $(o.options.containerSelector); - if (o.container.length == 0) { - o.container = o.sidebar.parent(); - } + for (const [key, value] of Object.entries({ + 'position': o.options.defaultPosition, + 'overflow': 'visible', + // The "box-sizing" must be set to "content-box" because we set a fixed height to this element when the sticky sidebar has a fixed position. + '-webkit-box-sizing': 'border-box', + '-moz-box-sizing': 'border-box', + 'box-sizing': 'border-box' + })) { + o.sidebar.style.setProperty(key, value); + } - // Create sticky sidebar - o.sidebar.parents().css('-webkit-transform', 'none'); // Fix for WebKit bug - https://code.google.com/p/chromium/issues/detail?id=20574 - o.sidebar.css({ - 'position': o.options.defaultPosition, - 'overflow': 'visible', - // The "box-sizing" must be set to "content-box" because we set a fixed height to this element when the sticky sidebar has a fixed position. - '-webkit-box-sizing': 'border-box', - '-moz-box-sizing': 'border-box', - 'box-sizing': 'border-box' + // Get the sticky sidebar element. If none has been found, then create one. + o.stickySidebar = o.sidebar.querySelector('.theiaStickySidebar'); + if (o.stickySidebar === null) { + // Remove