russellsamora / scrollama

Scrollytelling with IntersectionObserver.

Home Page:https://russellsamora.github.io/scrollama/basic

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

BUG: "rootMargin must be specified in pixels or percent."

sebastianwachter opened this issue · comments

After upgrading scrollama to version 2.1.0 IntersectionObserver throws an error:

DOMException: Failed to construct 'IntersectionObserver': rootMargin must be specified in pixels or percent.
    at eval (webpack-internal:///./node_modules/scrollama/build/scrollama.js:478:17)
    at Array.map (<anonymous>)
    at updateViewportAboveIO (webpack-internal:///./node_modules/scrollama/build/scrollama.js:472:31)
    at updateIO (webpack-internal:///./node_modules/scrollama/build/scrollama.js:543:5)
    at handleEnable (webpack-internal:///./node_modules/scrollama/build/scrollama.js:232:22)
    at Object.S.enable (webpack-internal:///./node_modules/scrollama/build/scrollama.js:618:5)
    at Object.S.setup (webpack-internal:///./node_modules/scrollama/build/scrollama.js:608:7)
    at VueComponent.init (webpack-internal:///./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/components/starting-page.vue:151:21)
    at VueComponent.mounted (webpack-internal:///./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/components/starting-page.vue:180:10)
    at invokeWithErrorHandling (webpack-internal:///./node_modules/vue/dist/vue.esm.js:1862:57)

This happens to the polyfilled version (for debugging reasons I copied the polyfill and used it as the replacement for the native vertsion therefore I called it "NonPolyfill") as well:

Error: rootMargin must be specified in pixels or percent
    at eval (IntersectionObserverNonPolyfill.js?e69e:233)
    at Array.map (<anonymous>)
    at IntersectionObserver._parseRootMargin (IntersectionObserverNonPolyfill.js?e69e:230)
    at new IntersectionObserver (IntersectionObserverNonPolyfill.js?e69e:87)
    at eval (scrollama.js?d11d:479)
    at Array.map (<anonymous>)
    at updateViewportAboveIO (scrollama.js?d11d:473)
    at updateIO (scrollama.js?d11d:544)
    at handleEnable (scrollama.js?d11d:233)
    at Object.S.enable (scrollama.js?d11d:619)

Using this replacement of the polyfill I was able to dig into what goes wrong and it seems that at the begining scrollama isn't able to construct a valid IntersectionObserver. Instead it passes NaN for some of its rootMargin values which causes the error:

NaNpx 0px -1730px 0px

I went on trying to fix this issue by regexing the NaN out and replacing it with the other non 0px numeric value found in the string. Until the IntersectionObserver would receive valid (non NaN) values. Which resulted in the following output (rootMargin is the original rootMargin passed to the IntersectionObserver and marginString is the margin string that I constructed):

{rootMargin: "NaNpx 0px -1730px 0px", marginString: "-1730px 0px -1730px 0px"}
{rootMargin: "NaNpx 0px -1730px 0px", marginString: "-1730px 0px -1730px 0px"}
{rootMargin: "NaNpx 0px -1730px 0px", marginString: "-1730px 0px -1730px 0px"}
{rootMargin: "NaNpx 0px -1730px 0px", marginString: "-1730px 0px -1730px 0px"}
{rootMargin: "NaNpx 0px -1730px 0px", marginString: "-1730px 0px -1730px 0px"}
{rootMargin: "-1730px 0px NaNpx 0px", marginString: "-1730px 0px -1730px 0px"}
{rootMargin: "-1730px 0px NaNpx 0px", marginString: "-1730px 0px -1730px 0px"}
{rootMargin: "-1730px 0px NaNpx 0px", marginString: "-1730px 0px -1730px 0px"}
{rootMargin: "-1730px 0px NaNpx 0px", marginString: "-1730px 0px -1730px 0px"}
{rootMargin: "-1730px 0px NaNpx 0px", marginString: "-1730px 0px -1730px 0px"}
{rootMargin: "430px 0px -650px 0px", marginString: "430px 0px -650px 0px"}
{rootMargin: "430px 0px -650px 0px", marginString: "430px 0px -650px 0px"}
{rootMargin: "430px 0px -650px 0px", marginString: "430px 0px -650px 0px"}
{rootMargin: "430px 0px -650px 0px", marginString: "430px 0px -650px 0px"}
{rootMargin: "430px 0px -650px 0px", marginString: "430px 0px -650px 0px"}
{rootMargin: "-650px 0px 430px 0px", marginString: "-650px 0px 430px 0px"}
{rootMargin: "-650px 0px 430px 0px", marginString: "-650px 0px 430px 0px"}
{rootMargin: "-650px 0px 430px 0px", marginString: "-650px 0px 430px 0px"}
{rootMargin: "-650px 0px 430px 0px", marginString: "-650px 0px 430px 0px"}
{rootMargin: "-650px 0px 430px 0px", marginString: "-650px 0px 430px 0px"}

By doing so I was able to fix the error but the functionality remained broken. The IntersectionObserver did only fire intersections in one direction (from top to bottom). In the other direction (bottom to top) it did nothing.

can you link to a browser report? https://mybrowser.fyi/

Sorry for the late reply but I was on vacation. Here is the browser report: https://mybrowser.fyi/report/5d8488a4ab4dae0015d725c8

@sebastianwachter, I had the same issue and traced it back to the scrollama setup, where I was specifying a container element within the scrollama.setup(). Prior to v2, the container could be a css selector, but as of v2, it must be a DOM element.

So, prior to v2, you could do this:

      scroller
        .setup({
          // ... other setup
          container: '#myCSSselector',
        });

but after v2 the container has to be a DOM element, or the DOM element sizing calculations fail (hence the NaN's in the rootMargin prop).

      scroller
        .setup({
          // ... other setup
          container: document.querySelector('#myCSSselector'),
        });

@russellgoldenberg, it seems like an easy fix to allow container to be a selector or DOM element by changing this line of code to:

containerEl = select(container);

Then again, I could see why you would want the user to specify a DOM element rather than a potentially non-specific css selector.

@sebastianwachter thanks - forgot to ask for the code snippet you are using to setup the scrollama instance too - in case it is something like @Ryshackleton mentioned (which I will address as well).

By selecting the element using querySelector fixed the issue for me. In the currently latest version (2.1.2) the old selection (without the querySelector) works as well.

Therefore I will close this. Thanks for your help.