WeCodePixels / theia-sticky-sidebar

Glues your website's sidebars, making them permanently visible while scrolling.
MIT License
569 stars 209 forks source link

Flickering During Browser Resize (SOLVED) #76

Open realDavidMeissner opened 1 month ago

realDavidMeissner commented 1 month ago

I ran into an issue with the script that occurs when the sidebar is sticky to top or bottom of view (and page content is not scrolled all the way up) and the browser is being resized.

I was able to narrow it down to the calls for o.stickySidebar.outerHeight(), which I believe is a jquery function. From there I realized that this was specifically occurring if the parent div (e.g. class="leftSidebar") was a different height than the nested sidebar div (e.g. class="theiaStickySidebar").

In my case, my structure involved a 3 col flex container with a css attribute for the parent of align-items: flex-start, which will set the height of each nested div to the height of it's content rather than 100%. Though it was necessary for the script to work with a flex box, this is what caused the variance in heights between the parent and child divs.

Here is my basic structure. (center column is not a sidebar column)

<div id="content">
    <div id="content-left">
        <div id="content-left-wrapper" class="sticky-sidebar"><!-- left sidebar content here --></div>
    </div>
    <div id="content-center">
        <div id="content-center-wrapper"><!-- main content here --></div>
    </div>
    <div id="content-right">
        <div id="content-right-wrapper" class="sticky-sidebar"><!-- right sidebar content here --></div>
    </div>
</div>

This is my call for a 3 column layout.

$(document).ready(function() {
    $('#content-left, #content-right')
        .sticky_sidebar({
            additionalMarginTop: 30
        });
});

What I had to do to resolve the issue was to set a new variable in the script for 'stickySidebarWrapper' based on the object being passed in the initial call. So if 'o.sidebar' referenced my '#content-left' element, then the script sets the value for 'stickySidebarWrapper' to '#content-left-wrapper' (my nested sidebar div).

Here is the code I used for this. Crude, but works.

/***
 * SET STICKY SIDEBAR WRAPPER.
 */
var sidebarId = o.sidebar[0].id; // Accessing the native DOM element's ID property
// console.log('Sidebar ID:', sidebarId);

var stickySidebarWrapper = '';
if(sidebarId === 'content-left')
    stickySidebarWrapper = $('#content-left-wrapper');
else if(sidebarId === 'content-center')
    stickySidebarWrapper = $('#content-center-wrapper');
else if(sidebarId === 'content-right')
    stickySidebarWrapper = $('#content-right-wrapper');
else
    stickySidebarWrapper = o.stickySidebar;

Then wherever o.stickySidebar.outerHeight() was called, I replaced it with stickySidebarWrapper.outerHeight() like this.

// var collapsedBottomHeight = o.stickySidebar.outerHeight();
var collapsedBottomHeight = stickySidebarWrapper.outerHeight();

The only exception to this was the last call made that set the min-height of the sidebar. Doing so had negative effect.

o.sidebar.css({
    'min-height': o.stickySidebar.outerHeight() + o.stickySidebar.offset().top - o.sidebar.offset().top + o.paddingBottom
});

Anyway, I hope this helps someone cause I spent the better part of today tracking this down and coming up with a fix (it sure helped me out).

If the developers see this as a valid issue then maybe they will take it into account and update the script accordingly. Other than that, this is really a great tool.