diff --git a/src/core/dom.js b/src/core/dom.js index ee5c3480b..cf9d7c1a4 100644 --- a/src/core/dom.js +++ b/src/core/dom.js @@ -177,11 +177,13 @@ function get_css_value(el, property, as_pixels = false, as_float = false) { * @param {String} [direction=] - Not given: Search for any scrollable element up in the DOM tree. * ``x``: Search for a horizontally scrollable element. * ``y``: Search for a vertically scrollable element. + * @param {(DOM Node|null)} [fallback=document.body] - Fallback, if no scroll container can be found. + * The default is to use document.body. * * @returns {Node} - Return the first scrollable element. * If no other element could be found, document.body would be returned. */ -const find_scroll_container = (el, direction) => { +const find_scroll_container = (el, direction, fallback = document.body) => { while (el && el !== document.body) { if (!direction || direction === "y") { let overflow_y = get_css_value(el, "overflow-y"); @@ -197,7 +199,7 @@ const find_scroll_container = (el, direction) => { } el = el.parentElement; } - return el; + return fallback; }; const dom = { diff --git a/src/core/dom.test.js b/src/core/dom.test.js index f8f9ca8b4..34f39a228 100644 --- a/src/core/dom.test.js +++ b/src/core/dom.test.js @@ -668,7 +668,7 @@ describe("core.dom tests", () => { expect(dom.find_scroll_container(div3, "x")).toBe(div1); done(); }); - it("returns document.body if nothing else is found", function (done) { + it("returns a fallback if given, if nothing else is found", function (done) { document.body.innerHTML = `
{
`; const div2 = document.querySelector("#div2"); - expect(dom.find_scroll_container(div2, "y")).toBe(document.body); + expect(dom.find_scroll_container(div2, "y", null)).toBe(null); done(); }); }); diff --git a/src/pat/bumper/bumper.js b/src/pat/bumper/bumper.js index 05ef6e8a7..bf9f894f9 100644 --- a/src/pat/bumper/bumper.js +++ b/src/pat/bumper/bumper.js @@ -43,8 +43,16 @@ export default Base.extend({ }, _init() { - const scroll_container_y = dom.find_scroll_container(this.el.parentElement, "y"); - const scroll_container_x = dom.find_scroll_container(this.el.parentElement, "x"); + const scroll_container_y = dom.find_scroll_container( + this.el.parentElement, + "y", + null + ); + const scroll_container_x = dom.find_scroll_container( + this.el.parentElement, + "x", + null + ); const pos = { top: dom.get_css_value(this.el, "top", true), @@ -52,28 +60,28 @@ export default Base.extend({ bottom: dom.get_css_value(this.el, "bottom", true), left: dom.get_css_value(this.el, "left", true), }; - const intersection_observer_config_y = { + const intersection_observer_config = { threshold: [1, 0.99, 0.97, 0.96, 0.95, 0.94, 0.93, 0.92, 0.91, 0.9], - root: scroll_container_y, // add margin as inverted sticky positions. rootMargin: `${-pos.top - 1}px ${-pos.right - 1}px ${-pos.bottom - 1}px ${-pos.left - 1}px`, // prettier-ignore }; const observer_y = new IntersectionObserver( this._intersection_observer_callback.bind(this), - intersection_observer_config_y + { + ...intersection_observer_config, + root: scroll_container_y, + } ); observer_y.observe(this.el); if (scroll_container_x !== scroll_container_y) { - const intersection_observer_config_x = Object.assign( - {}, - intersection_observer_config_y, - { root: scroll_container_x } - ); const observer_x = new IntersectionObserver( this._intersection_observer_callback.bind(this), - intersection_observer_config_x + { + ...intersection_observer_config, + root: scroll_container_x, + } ); observer_x.observe(this.el); } diff --git a/src/pat/bumper/index.html b/src/pat/bumper/index.html index 5b3c73776..d18b50e78 100644 --- a/src/pat/bumper/index.html +++ b/src/pat/bumper/index.html @@ -88,7 +88,7 @@
Making some space to the left
-
+
Sticky bar.