PageSourceSearch

https://themaneland.com/wp-content/plugins/theia-sticky-sidebar/js/theia-sticky-sidebar.js?ver=1.7.0

js themaneland.com collected 2026-10-01 11:43:34 UTC 15,926 bytes, 366 lines download raw bytes

1/*!
2 * Theia Sticky Sidebar v1.6.0
3 * https://github.com/WeCodePixels/theia-sticky-sidebar
4 *
5 * Glues your website's sidebars, making them permanently visible while scrolling.
6 *
7 * Copyright 2013-2016 WeCodePixels and other contributors
8 * Released under the MIT license
9 */
10
11(function ($) {
12    $.fn.theiaStickySidebar = function (options) {
13        var defaults = {
14            'containerSelector': '',
15            'additionalMarginTop': 0,
16            'additionalMarginBottom': 0,
17            'updateSidebarHeight': true,
18            'minWidth': 0,
19            'disableOnResponsiveLayouts': true,
20            'sidebarBehavior': 'modern'
21        };
22        options = $.extend(defaults, options);
23
24        // Validate options
25        options.additionalMarginTop = parseInt(options.additionalMarginTop) || 0;
26        options.additionalMarginBottom = parseInt(options.additionalMarginBottom) || 0;
27
28        tryInitOrHookIntoEvents(options, this);
29
30        // Try doing init, otherwise hook into window.resize and document.scroll and try again then.
31        function tryInitOrHookIntoEvents(options, $that) {
32            var success = tryInit(options, $that);
33
34            if (!success) {
35                console.log('TSS: Body width smaller than options.minWidth. Init is delayed.');
36
37                $(document).scroll(function (options, $that) {
38                    return function (evt) {
39                        var success = tryInit(options, $that);
40
41                        if (success) {
42                            $(this).unbind(evt);
43                        }
44                    };
45                }(options, $that));
46                $(window).resize(function (options, $that) {
47                    return function (evt) {
48                        var success = tryInit(options, $that);
49
50                        if (success) {
51                            $(this).unbind(evt);
52                        }
53                    };
54                }(options, $that))
55            }
56        }
57
58        // Try doing init if proper conditions are met.
59        function tryInit(options, $that) {
60            if (options.initialized === true) {
61                return true;
62            }
63
64            if ($('body').width() < options.minWidth) {
65                return false;
66            }
67
68            init(options, $that);
69
70            return true;
71        }
72
73        // Init the sticky sidebar(s).
74        function init(options, $that) {
75            options.initialized = true;
76
77            // Add CSS
78            $('head').append($('<style>.theiaStickySidebar:after {content: ""; display: table; clear: both;}</style>'));
79
80            $that.each(function () {
81                var o = {};
82
83                o.sidebar = $(this);
84
85                // Save options
86                o.options = options || {};
87
88                // Get container
89                o.container = $(o.options.containerSelector);
90                if (o.container.length == 0) {
91                    o.container = o.sidebar.parent();
92                }
93
94                // Create sticky sidebar
95                o.sidebar.parents().css('-webkit-transform', 'none'); // Fix for WebKit bug - https://code.google.com/p/chromium/issues/detail?id=20574
96                o.sidebar.css({
97                    'position': 'relative',
98                    'overflow': 'visible',
99                    // The "box-sizing" must be set to "content-box" because we set a fixed height to this element when the sticky 
99sidebar has a fixed position.
100                    '-webkit-box-sizing': 'border-box',
101                    '-moz-box-sizing': 'border-box',
102                    'box-sizing': 'border-box'
103                });
104
105                // Get the sticky sidebar element. If none has been found, then create one.
106                o.stickySidebar = o.sidebar.find('.theiaStickySidebar');
107                if (o.stickySidebar.length == 0) {
108                    // Remove <script> tags, otherwise they will be run again when added to the stickySidebar.
109                    var javaScriptMIMETypes = /(?:text|application)\/(?:x-)?(?:javascript|ecmascript)/i;
110                    o.sidebar.find('script').filter(function (index, script) {
111                        return script.type.length === 0 || script.type.match(javaScriptMIMETypes);
112                    }).remove();
113
114                    o.stickySidebar = $('<div>').addClass('theiaStickySidebar').append(o.sidebar.children());
115                    o.sidebar.append(o.stickySidebar);
116                }
117
118                // Get existing top and bottom margins and paddings
119                o.marginBottom = parseInt(o.sidebar.css('margin-bottom'));
120                o.paddingTop = parseInt(o.sidebar.css('padding-top'));
121                o.paddingBottom = parseInt(o.sidebar.css('padding-bottom'));
122
123                // Add a temporary padding rule to check for collapsable margins.
124                var collapsedTopHeight = o.stickySidebar.offset().top;
125                var collapsedBottomHeight = o.stickySidebar.outerHeight();
126                o.stickySidebar.css('padding-top', 1);
127                o.stickySidebar.css('padding-bottom', 1);
128                collapsedTopHeight -= o.stickySidebar.offset().top;
129                collapsedBottomHeight = o.stickySidebar.outerHeight() - collapsedBottomHeight - collapsedTopHeight;
130                if (collapsedTopHeight == 0) {
131                    o.stickySidebar.css('padding-top', 0);
132                    o.stickySidebarPaddingTop = 0;
133                }
134                else {
135                    o.stickySidebarPaddingTop = 1;
136                }
137
138                if (collapsedBottomHeight == 0) {
139                    o.stickySidebar.css('padding-bottom', 0);
140                    o.stickySidebarPaddingBottom = 0;
141                }
142                else {
143                    o.stickySidebarPaddingBottom = 1;
144                }
145
146                // We use this to know whether the user is scrolling up or down.
147                o.previousScrollTop = null;
148
149                // Scroll top (value) when the sidebar has fixed position.
150                o.fixedScrollTop = 0;
151
152                // Set sidebar to default values.
153                resetSidebar();
154
155                o.onScroll = function (o) {
156                    // Stop if the sidebar isn't visible.
157                    if (!o.stickySidebar.is(":visible")) {
158                        return;
159                    }
160
161                    // Stop if the window is too small.
162                    if ($('body').width() < o.options.minWidth) {
163                        resetSidebar();
164                        return;
165                    }
166
167                    // Stop if the sidebar width is larger than the container width (e.g. the theme is responsive and the sidebar is now below the content)
168                    if (o.options.disableOnResponsiveLayouts) {
169                        var sidebarWidth = o.sidebar.outerWidth(o.sidebar.css('float') == 'none');
170
171                        if (sidebarWidth + 50 > o.container.width()) {
172                            resetSidebar();
173                            return;
174                        }
175                    }
176
177                    var scrollTop = $(document).scrollTop();
178                    var position = 'static';
179
180                    // If the user has scrolled down enough for the sidebar to be clipped at the top, then we can consider changing its position.
181                    if (scrollTop >= o.sidebar.offset().top + (o.paddingTop - o.options.additionalMarginTop)) {
182                        // The top and bottom offsets, used in various calculations.
183                        var offsetTop = o.paddingTop + options.additionalMarginTop;
184                        var offsetBottom = o.paddingBottom + o.marginBottom + options.additionalMarginBottom;
185
186                        // All top and bottom positions are relative to the window, not to the parent elemnts.
187                        var containerTop = o.sidebar.offset().top;
188                        var containerBottom = o.sidebar.offset().top + getClearedHeight(o.container);
189
190                        // The top and bottom offsets relative to the window screen top (zero) and bottom (window height).
191                        var windowOffsetTop = 0 + options.additionalMarginTop;
192                        var windowOffsetBottom;
193
194                        var sidebarSmallerThanWindow = (o.stickySidebar.outerHeight() + offsetTop + offsetBottom) < $(window).height();
195                        if (sidebarSmallerThanWindow) {
196                            windowOffsetBottom = windowOffsetTop + o.stickySidebar.outerHeight();
197                        }
198                        else {
199                            windowOffsetBottom = $(window).height() - o.marginBottom - o.paddingBottom - options.additionalMarginBottom;
200                        }
201
202                        var staticLimitTop = containerTop - scrollTop + o.paddingTop;
203                        var staticLimitBottom = containerBottom - scrollTop - o.paddingBottom - o.marginBottom;
204
205                        var top = o.stickySidebar.offset().top - scrollTop;
206                        var scrollTopDiff = o.previousScrollTop - scrollTop;
207
208                        // If the sidebar position is fixed, then it won't move up or down by itself. So, we manually adjust the top coordinate.
209                        if (o.stickySidebar.css('position') == 'fixed') {
210                            if (o.options.sidebarBehavior == 'modern') {
211                                top += scrollTopDiff;
212                            }
213                        }
214
215                        if (o.options.sidebarBehavior == 'stick-to-top') {
216                            top = options.additionalMarginTop;
217                        }
218
219                        if (o.options.sidebarBehavior == 'stick-to-bottom') {
220                            top = windowOffsetBottom - o.stickySidebar.outerHeight();
221                        }
222
223                        if (scrollTopDiff > 0) { // If the user is scrolling up.
224                            top = Math.min(top, windowOffsetTop);
225                        }
226                        else { // If the user is scrolling down.
227                            top = Math.max(top, windowOffsetBottom - o.stickySidebar.outerHeight());
228                        }
229
230                        top = Math.max(top, staticLimitTop);
231
232                        top = Math.min(top, staticLimitBottom - o.stickySidebar.outerHeight());
233
234                        // If the sidebar is the same height as the container, we won't use fixed positioning.
235                        var sidebarSameHeightAsContainer = o.container.height() == o.stickySidebar.outerHeight();
236
237                        if (!sidebarSameHeightAsContainer && top == windowOffsetTop) {
238                            position = 'fixed';
239                        }
240                        else if (!sidebarSameHeightAsContainer && top == windowOffsetBottom - o.stickySidebar.outerHeight()) {
241                            position = 'fixed';
242                        }
243                        else if (scrollTop + top - o.sidebar.offset().top - o.paddingTop <= options.additionalMarginTop) {
244                            // Stuck to the top of the page. No special behavior.
245                            position = 'static';
246                        }
247                        else {
248                            // Stuck to the bottom of the page.
249                            position = 'absolute';
250                        }
251                    }
252
253                    /*
254                     * Performance notice: It's OK to set these CSS values at each resize/scroll, even if they don't change.
255                     * It's way slower to first check if the values have changed.
256                     */
257                    if (position == 'fixed') {
258                        var scrollLeft = $(document).scrollLeft();
259
260                        o.stickySidebar.css({
261                            'position': 'fixed',
262                            'width': getWidthForObject(o.stickySidebar) + 'px',
263                            'transform': 'translateY(' + top + 'px)',
264                            'left': (o.sidebar.offset().left + parseInt(o.sidebar.css('padding-left')) - scrollLeft) + 'px',
265                            'top': '0px'
266                        });
267                    }
268                    else if (position == 'absolute') {
269                        var css = {};
270
271                        if (o.stickySidebar.css('position') != 'absolute') {
272                            css.position = 'absolute';
273                            css.transform = 'translateY(' + (scrollTop + top - o.sidebar.offset().top - o.stickySidebarPaddingTop - o.stickySidebarPaddingBottom) + 'px)';
274                            css.top = '0px';
275                        }
276
277                        css.width = getWidthForObject(o.stickySidebar) + 'px';
278                        css.left = '';
279
280                        o.stickySidebar.css(css);
281                    }
282                    else if (position == 'static') {
283                        resetSidebar();
284                    }
285
286                    if (position != 'static') {
287                        if (o.options.updateSidebarHeight == true) {
288                            o.sidebar.css({
289                                'min-height': o.stickySidebar.outerHeight() + o.stickySidebar.offset().top - o.sidebar.offset().top + o.paddingBottom
290                            });
291                        }
292                    }
293
294                    o.previousScrollTop = scrollTop;
295                };
296
297                // Initialize the sidebar's position.
298                o.onScroll(o);
299
300                // Recalculate the sidebar's position on every scroll and resize.
301                $(document).scroll(function (o) {
302                    return function () {
303                        o.onScroll(o);
304                    };
305                }(o));
306                $(window).resize(function (o) {
307                    return function () {
308                        o.stickySidebar.css({'position': 'static'});
309                        o.onScroll(o);
310                    };
311                }(o));
312
313                // Recalculate the sidebar's position every time the sidebar changes its size.
314                if (typeof ResizeSensor !== 'undefined') {
315                    new ResizeSensor(o.stickySidebar[0], function (o) {
316                        return function () {
317                            o.onScroll(o);
318                        };
319                    }(o));
320                }
321
322                // Reset the sidebar to its default state
323                function resetSidebar() {
324                    o.fixedScrollTop = 0;
325                    o.sidebar.css({
326                        'min-height': '1px'
327                    });
328                    o.stickySidebar.css({
329                        'position': 'static',
330                        'width': '',
331                        'transform': 'none'
332                    });
333                }
334
335                // Get the height of a div as if its floated children were cleared. Note that this function fails if the floats are more than one level deep.
336                function getClearedHeight(e) {
337                    var height = e.height();
338
339                    e.children().each(function () {
340                        height = Math.max(height, $(this).height());
341                    });
342
343                    return height;
344                }
345            });
346        }
347
348        function getWidthForObject(object) {
349            var width;
350
351            try {
352                width = object[0].getBoundingClientRect().width;
353            }
354            catch (err) {
355            }
356
357            if (typeof width === "undefined") {
358                width = object.width();
359            }
360
361            return width;
362        }
363    }
364})(jQuery);
365
366//# sourceMappingURL=maps/theia-sticky-sidebar.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.