kovart / sticksy

🧲 Blazing fast sticky widgets in one line! (Sidebar friendly)
https://sticksy.js.org
MIT License
196 stars 24 forks source link

Dynamic topSpacing ? #3

Open Stibo opened 3 years ago

Stibo commented 3 years ago

Hi

Is it possible to change the topSpacing value "on-the-fly"? We have a responsive sticky header that changes height during scroll or resize (and at some point disappears completely) and a sidebar that has always the same distance to the header (or the top document border if the header is not visible). If we scroll, the sidebar pans with a spacing (like 50px) from the header that is 100px in height. So the sidebar should be positioned 150px from the top document border. If the header shrinks to 50px, the sidebar should be 100px from the top document. And if the header dissapears completely, the sidebar distance between document top and sidebar should be 50px. Is this possible with your sticky plugin? Can I overwrite the topSpacing value while the script is already running? Or does topSpacing support a dynamic function?

vladdancer commented 2 years ago

We had also this issue but in the context of dynamic main content region with top sticky header. Here is workaround:

// File with content observer callback.
const resizedEvent = new CustomEvent("b5Theme.resizeObserver.observeContentRegion", {
  bubbles: true,
  detail: {
    width: rect.width,
    height: rect.height
  }
});
element.target.dispatchEvent(resizedEvent);
// File with sticksy handler.
const defaultBlockPadding = 20;

let stickyEl = new Sticksy('.block-fixed-on-scroll', {
  topSpacing: defaultBlockPadding
});

window.addEventListener(
  "b5Theme.resizeObserver.observeContentRegion",
  e => {
    const contentHeight = e.detail.height;

    if (sidebar) {
      sidebar.style.height = `${contentHeight}px`;
    }

    // In sticksy's minified version there is no "_props" property.
    const props = stickyEl?._props ?? stickyEl?.t ?? false;

    if (props) {
      // Fix also sticky block padding when admin toolbar is on the page.
      const bodyPaddingTop = parseInt(body.style.paddingTop || 0);
      props.topSpacing = bodyPaddingTop + defaultBlockPadding;
    }
    stickyEl.hardRefresh();
  }
);

The key here: stickyEl._props.topSpacing = value;

Stibo commented 2 years ago

That sounds great, thanks for sharing! We'll try that out in our next project.

Still, would be nice if this feature would be supported by the plugin itself, without work around.

vladdancer commented 2 years ago

I'm glad if this could help you!