Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling enableBodyScroll can disable body scroll depending on situation #74

Open
maeertin opened this issue Nov 16, 2018 · 5 comments
Open

Comments

@maeertin
Copy link

Hey there, thank you for this cool library.

So the issue can be reproduced with the code below:

disableBodyScroll(targetElement)
setTimeout(() => {
  document.body.removeAttribute('style')
}, 100)
setTimeout(() => {
  enableBodyScroll(targetElement) // this will disable scrolling
}, 200)

In my case, I'm using material-ui where it's Dialog component already handles setting/removing of overflow: hidden on document.body and therefore end up in a similar situation as above. Sadly this css trick alone does not cancel scrolling on iOS and was hoping to use this library.

@willmcpo
Copy link
Owner

willmcpo commented Nov 16, 2018 via email

@maeertin
Copy link
Author

maeertin commented Nov 19, 2018

Hey, thanks @willmcpo for the quick response!

Elaborating on my scenario
So I did some more digging into this and there seems to have been more to it then I thought. So the problem starts already when I call disableBodyScroll as this will set the restore values that you mention. In my case these saved restore values are incorrect due to material-ui/Dialog setting overflow: hidden to document.body before disableBodyScroll is fired, and therefore calling enableBodyScroll does not work. Don't really know how to go about this issue but I somehow expected that enableBodyScroll would enable body scrolling regardless of when I might have called disableBodyScroll.

The issue
Incorrect restore values being saved and no way to correct them.

Suggestion
What if the library exposed a function to either update the previousBody... vars or one that set some similar initialBody... vars to be used instead if defined?

Demo
I recreated a condensed example of the issue in this CodeSandbox where I use your library within the ScrollLock component.
https://codesandbox.io/s/50nkpljo9l

@maeertin
Copy link
Author

Since this is a compatibility issue with handling of overflow: hidden on document.body, another solution would be to let lib users opt in/out of the css/js solutions of scroll canceling.

@maeertin
Copy link
Author

I see that you already forward the options object to the function setOverflowHidden. What if this function was updated to something like below to allow control of the restore values.

const setOverflowHidden = (options = {}) => {
  const {
    reserveScrollBarGap,
    restoreBodyPaddingRight: optionsBPR,
    restoreBodyOverflowSetting: optionsBOS,
  } = options

  // Setting overflow on body/documentElement synchronously in Desktop Safari slows down
  // the responsiveness for some reason. Setting within a setTimeout fixes this.
  setTimeout(() => {
    // If previousBodyPaddingRight is already set, don't set it again.
    if (previousBodyPaddingRight === undefined) {
      const scrollBarGap = window.innerWidth - document.documentElement.clientWidth

      if (reserveScrollBarGap && scrollBarGap > 0) {
        // type-check against undefined to allow falsy values
        previousBodyPaddingRight = optionsBPR !== undefined
            ? optionsBPR
            : document.body.style.paddingRight
        document.body.style.paddingRight = `${scrollBarGap}px`
      }
    }

    // If previousBodyOverflowSetting is already set, don't set it again.
    if (previousBodyOverflowSetting === undefined) {
      // type-check against undefined to allow falsy values
      previousBodyOverflowSetting = optionsBOS !== undefined
        ? optionsBOS
        : document.body.style.overflow
      document.body.style.overflow = 'hidden'
    }
  })
}

@willmcpo
Copy link
Owner

from a quick glimpse, seems ok and intuitive.

would you mind putting that in a PR ? =) 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants