PageSourceSearch

https://popco-opband.com/packages/c5box_sidebar/themes/sidebar/js/sticky.js

js popco-opband.com collected 2026-10-02 11:44:09 UTC 11,805 bytes, 268 lines download raw bytes

1/*!
2 * Theia Sticky Sidebar v1.2.2
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-2014 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        };
20        options = $.extend(defaults, options);
21
22        // Validate options
23        options.additionalMarginTop = parseInt(options.additionalMarginTop) || 0;
24        options.additionalMarginBottom = parseInt(options.additionalMarginBottom) || 0;
25        
26        // Add CSS
27        $('head').append($('<style>.theiaStickySidebar:after {content: ""; display: table; clear: both;}</style>'));
28
29        this.each(function() {
30            var o = {};
31            o.sidebar = $(this);
32
33            // Save options
34            o.options = options || {};
35
36            // Get container
37            o.container = $(o.options.containerSelector);
38            if (o.container.size() == 0) {
39                o.container = o.sidebar.parent();
40            }
41
42            // Create sticky sidebar
43            o.sidebar.parents().css('-webkit-transform', 'none'); // Fix for WebKit bug - https://code.google.com/p/chromium/issues/detail?id=20574
44            o.sidebar.css({
45                'position': 'relative',
46                'overflow': 'visible',
47                // The "box-sizing" must be set to "content-box" because we set a fixed height to this element when the sticky 
47sidebar has a fixed position.
48                '-webkit-box-sizing': 'border-box',
49                '-moz-box-sizing': 'border-box',
50                'box-sizing': 'border-box'
51            });
52            
53            // Get the sticky sidebar element. If none has been found, then create one.
54            o.stickySidebar = o.sidebar.find('.theiaStickySidebar');
55            if (o.stickySidebar.length == 0) {              
56                o.sidebar.find('script').remove(); // Remove <script> tags, otherwise they will be run again on the next line.
57                o.stickySidebar = $('<div>').addClass('theiaStickySidebar').append(o.sidebar.children());               
58                o.sidebar.append(o.stickySidebar);
59            }
60
61            // Get existing top and bottom margins and paddings
62            o.marginTop = parseInt(o.sidebar.css('margin-top'));
63            o.marginBottom = parseInt(o.sidebar.css('margin-bottom'));
64            o.paddingTop = parseInt(o.sidebar.css('padding-top'));
65            o.paddingBottom = parseInt(o.sidebar.css('padding-bottom'));
66
67            // Add a temporary padding rule to check for collapsable margins.
68            var collapsedTopHeight = o.stickySidebar.offset().top;
69            var collapsedBottomHeight = o.stickySidebar.outerHeight();
70            o.stickySidebar.css('padding-top', 1);
71            o.stickySidebar.css('padding-bottom', 1);
72            collapsedTopHeight -= o.stickySidebar.offset().top;
73            collapsedBottomHeight = o.stickySidebar.outerHeight() - collapsedBottomHeight - collapsedTopHeight;
74            if (collapsedTopHeight == 0) {
75                o.stickySidebar.css('padding-top', 0);
76                o.stickySidebarPaddingTop = 0;
77            }
78            else {
79                o.stickySidebarPaddingTop = 1;
80            }
81            
82            if (collapsedBottomHeight == 0) {
83                o.stickySidebar.css('padding-bottom', 0);
84                o.stickySidebarPaddingBottom = 0;
85            }
86            else {
87                o.stickySidebarPaddingBottom = 1;
88            }
89
90            // We use this to know whether the user is scrolling up or down.
91            o.previousScrollTop = null;
92
93            // Scroll top (value) when the sidebar has fixed position.
94            o.fixedScrollTop = 0;
95            
96            // Set sidebar to default values.
97            resetSidebar();
98
99            o.onScroll = function(o) {
100                // Stop if the sidebar isn't visible.
101                if (!o.stickySidebar.is(":visible")) {
102                    return;
103                }               
104                
105                // Stop if the window is too small.
106                if ($('body').width() < o.options.minWidth) {
107                    resetSidebar();
108                    return;                 
109                }
110
111                // 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)
112                if (o.sidebar.outerWidth(true) + 50 >  o.container.width()) {
113                    resetSidebar();
114                    return;
115                }
116
117                var scrollTop = $(document).scrollTop();
118                var position = 'static';
119
120                // If the user has scrolled down enough for the sidebar to be clipped at the top, then we can consider changing its position.
121                if (scrollTop >= o.container.offset().top + (o.paddingTop + o.marginTop - o.options.additionalMarginTop)) {
122                    // The top and bottom offsets, used in various calculations.
123                    var offsetTop = o.paddingTop + o.marginTop + options.additionalMarginTop;
124                    var offsetBottom =  o.paddingBottom + o.marginBottom + options.additionalMarginBottom;
125                    
126                    // All top and bottom positions are relative to the window, not to the parent elemnts.
127                    var containerTop = o.container.offset().top;
128                    var containerBottom = o.container.offset().top + getClearedHeight(o.container);
129                    
130                    // The top and bottom offsets relative to the window screen top (zero) and bottom (window height).
131                    var windowOffsetTop = 0 + options.additionalMarginTop;
132                    var windowOffsetBottom;
133                    
134                    var sidebarSmallerThanWindow = (o.stickySidebar.outerHeight() + offsetTop + offsetBottom) < $(window).height();
135                    if (sidebarSmallerThanWindow) {
136                        windowOffsetBottom = windowOffsetTop + o.stickySidebar.outerHeight();
137                    }
138                    else {
139                        windowOffsetBottom = $(window).height() - o.marginBottom - o.paddingBottom - options.additionalMarginBottom;
140                    }
141                    
142                    var staticLimitTop = containerTop - scrollTop + o.paddingTop + o.marginTop;
143                    var staticLimitBottom = containerBottom - scrollTop - o.paddingBottom - o.marginBottom;
144
145                    var top = o.stickySidebar.offset().top - scrollTop;
146                    var scrollTopDiff = o.previousScrollTop - scrollTop;
147                    
148                    // If the sidebar position is fixed, then it won't move up or down by itself. So, we manually adjust the top coordinate.
149                    if (o.stickySidebar.css('position') == 'fixed') {
150                        top += scrollTopDiff;
151                    }
152                    
153                    if (scrollTopDiff > 0) { // If the user is scrolling up.
154                        top = Math.min(top, windowOffsetTop);
155                    }
156                    else { // If the user is scrolling down.
157                        top = Math.max(top, windowOffsetBottom - o.stickySidebar.outerHeight());
158                    }
159
160                    top = Math.max(top, staticLimitTop);
161
162                    top = Math.min(top, staticLimitBottom - o.stickySidebar.outerHeight());
163                    
164                    // If the sidebar is the same height as the container, we won't use fixed positioning.
165                    var sidebarSameHeightAsContainer = o.container.height() == o.stickySidebar.outerHeight();
166                    
167                    if (!sidebarSameHeightAsContainer && top == windowOffsetTop) {
168                        position = 'fixed';
169                    }
170                    else if (!sidebarSameHeightAsContainer && top == windowOffsetBottom - o.stickySidebar.outerHeight()) {
171                        position = 'fixed';
172                    }
173                    else if (scrollTop + top - o.sidebar.offset().top - o.paddingTop <= options.additionalMarginTop) {
174                        position = 'static';
175                    }
176                    else {
177                        position = 'absolute';
178                    }
179                }
180
181                /*
182                 * Performance notice: It's OK to set these CSS values at each resize/scroll, even if they don't change.
183                 * It's way slower to first check if the values have changed.
184                 */
185                if (position == 'fixed') {
186                    o.stickySidebar.css({
187                        'position': 'fixed',
188                        'width': o.sidebar.width(),
189                        'top': top,
190                        'left': o.sidebar.offset().left + parseInt(o.sidebar.css('padding-left'))
191                    });
192                }
193                else if (position == 'absolute') {
194                    var css = {};
195
196                    if (o.stickySidebar.css('position') != 'absolute') {
197                        css.position = 'absolute';
198                        css.top = scrollTop + top - o.sidebar.offset().top - o.stickySidebarPaddingTop - o.stickySidebarPaddingBottom;
199                    }
200
201                    css.width = o.sidebar.width();
202                    css.left = '';
203
204                    o.stickySidebar.css(css);
205                }
206                else if (position == 'static') {
207                    resetSidebar();
208                }
209
210                if (position != 'static') {
211                    if (o.options.updateSidebarHeight == true) {
212                        o.sidebar.css({
213                            'min-height': o.stickySidebar.outerHeight() + o.stickySidebar.offset().top - o.sidebar.offset().top + o.paddingBottom
214                        });
215                    }
216                }
217                
218                o.previousScrollTop = scrollTop;
219            };
220
221            // Initialize the sidebar's position.
222            o.onScroll(o);
223
224            // Recalculate the sidebar's position on every scroll and resize.
225            $(document).scroll(function(o) {
226                return function() {
227                    o.onScroll(o);
228                };
229            }(o));
230            $(window).resize(function(o) {
231                return function() {
232                    o.stickySidebar.css({'position': 'static'});
233                    o.onScroll(o);
234                };
235            }(o));
236
237            // Reset the sidebar to its default state
238            function resetSidebar() {
239                o.fixedScrollTop = 0;
240                o.sidebar.css({
241                    'min-height': '1px'
242                });
243                o.stickySidebar.css({
244                    'position': 'static',
245                    'width': ''
246                });
247            }
248
249            // 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.
250            function getClearedHeight(e) {
251                var height = e.height();
252
253                e.children().each(function() {
254                    height = Math.max(height, $(this).height());
255                });
256
257                return height;
258            }
259        });
260    }
261})(jQuery);
262
263  jQuery(document).ready(function() {
264    jQuery('.stickyside').theiaStickySidebar({
265      // Settings
266      additionalMarginTop: 30
267    });
268  });

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.