Giter Site home page Giter Site logo

willmcpo / body-scroll-lock Goto Github PK

View Code? Open in Web Editor NEW
4.0K 30.0 337.0 19.85 MB

Body scroll locking that just works with everything ๐Ÿ˜

License: MIT License

JavaScript 100.00%
body-scroll-lock react-scroll-lock scroll-lock body-scroll react vanilla-js angular modal lightbox ios

body-scroll-lock's People

Contributors

adrienharnay avatar alaskaa avatar an-cu avatar beauroberts avatar danielvonmitschke avatar davidweatherall avatar dependabot[bot] avatar fzembow avatar helgenlechner avatar iwbc avatar jamesdiacono avatar jokero avatar jvitela avatar larsdenbakker avatar liamcmitchell-sc avatar limonte avatar martinkutter avatar neddz avatar rogerpodacter avatar vltansky avatar vspedr avatar websocket98765 avatar willmcpo avatar willpox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

body-scroll-lock's Issues

.includes('Safari') is not compatible with Mobile Safari before version 9

in lib/utils/userAgent.js

typeof window !== 'undefined' && isMobileOrTablet && getBrowser().name.includes('Safari');

Since this is used to detect user-agents and scroll lock all safari versions I'd assume that the detection for Safari UA would be more backwards compatible.

Can you cage it from getBrsrResult.name.includes('Safari')
to
getBrsrResult.name.indexOf('Safari') >= 0

Please, so I don't have to branch my own off...

Doesn't work on iOs 9+

I couldn't get this to work on my project so I started testing the example provided.

It seems that the body scroll lock does not work on iOS 9 and above, including the current 11. It works on iOS 8.

Calling disableBodyScroll scrolls to the top on the first time and removes scroll listener

Hi, I am running into an issue with disableBodyScroll.

On the first time I call this method on my target element my page scrolls to the top and after that my window scroll event listener stops being called, I tried adding the listener again after disabling the body scroll but no success, it's like the listener event gets completely blocked. Any ideas why this is happening?

Thank you for the great package by the way.

Doesn't work on Android

Hi, I try to use body-scroll-lock for the website I'm currently developing but I can that on my Android with Chrome 70.0.3538.64 it simply doesn't work.

However, if I add overflow: hidden to the html tag instead of the body, it works.
I still have to make a few tests to make sure I don't have to switch between the body and the html for cross-browser compatibility but I'll go with that for now.

"SyntaxError: unexpected token"

Hi,

Am getting "SyntaxError: unexpected token: identifier" on row "type HandleScrollEvent = TouchEvent;" on the bodyScrollLock.js script when importing it like this: ---> script(src='/public/lib/bodyScrollLock.js')

Do you need to have requirejs in order to import the script?

http://requirejs.org/docs/download.html ?

Calling enableBodyScroll can disable body scroll depending on situation

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.

Incorrect assumption when to enable scrolling

Enabling scrolling is done based on whether the firstTargetElement was enabled. This is incorrect as the first element could be finished and allow scrolling while other elements still need the blocking.

For example:

  • Dialog A opens, calls disableBodyScroll() and becomes firstTargetElement

  • Dialog B opens, calls disableBodyScroll()

  • Dialog A closes, calls enableBodyScroll() and matches firstTargetElement and thus scrolling is allowed

  • Dialog B is now opened with background scrolling enabled

Scrollable list in modal view

Thank you for your awesome work. I have one question. I have an model view with an scrollable list within. With disableBodyScroll(document.querySelector("#modalView")); the body is not scrollable but im not able to scroll in the list within the modal. If a add disableBodyScroll(document.querySelector("#scrollableListInModalView")); to the list in the modal, the list is scrollable and the body is also not scrollable, this is fine! But when I scroll, for example on the modal header, the body starts scrolling. Is there a way to solve this problem ?

Thank you

Get current status

Hello,

I have an issue where the body can be scrolled again, as soon as I open the submenu (a class is added to the body tag). I would like to find out what is going here and therefore it would come in handy to be able to read the current status - I mean if bodyScroll is disabled or not. I haven't found any possibility to do this right now.

Thanks for your help!

Issues when reverting the overflow value

Hi, and thanks for your work on this package!

We ran into a problem while using it though. When the locks are removed, the overflow value of the body is reset to whatever it was earlier. But sometimes that earlier value is wrong by the time the lock needs to be removed.

I made a small codepen example to demonstrate the problem โ€” you can toggle the bug on and off with a variable in the js file.

A safer way to do this would be to use a class to apply the overflow: hidden, presumably with an !important so it overrides any lingering inline styles. And when the class is removed, whatever other rule should apply will take over again.

Does that sound ok to you? Would you be willing to make that change, or consider a PR that implements it?

How to use this without npm or require?

This project looks useful but overly burdensome to install.

On the risk of loosing my front-end hipster creds: I don't want to use npm or yarn or require for my simple website project. All I want is to include a js file with a script tag and use this functionality. Is that possible?

By default, should children elements within Locked elements be allowed touch move?

Referring to a comment by @liamcmitchell-sc ,

the API of allowTouchMove requires implementations of allowTouchMove to implement the same available scroll checks that this library is doing. This is a lot to expect of consumers to enable correct scrolling. I think the nicest behaviour for consumers of this library is to provide the most complete solution by default.

wanted to understand what the ratio of yes votes vs no votes for this one?

Click events inside scrollable target triggers JS error

Click events inside scrollable target container trigger an error
image

Here is a Vue component example:

<script>
import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock';

export default {
    data() {
        return {
            show: false,
            scrollTarget: '',
        };
    },

    methods: {
        open() {
            this.show = true;
            disableBodyScroll(this.scrollTarget);
        },

        close() {
            enableBodyScroll(this.scrollTarget);
            this.show = false;
        },
    },

    mounted() {
        this.scrollTarget = document.querySelector('#full-screen-preview')
    },
};
</script>

<template>
    <div v-if="show" id="full-screen-preview">
        <a href="#" @click.prevent="close">X</a>
        <img src="..." alt="...">
    </div>
</template>

<style lang="scss" scoped>
    #full-screen-preview {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        overflow-y: scroll;
        -webkit-overflow-scrolling: touch;
        background: #390423;
    }

    // Other layout styles here.
</style>

Include source map in NPM package

It's frustrating being unable to step into the methods exposed by this module, could either the source or a source map be included in the package?

Incompatible with Leaflet.js

Leaflet.js is a library for interactive maps (like Google Maps). A map to properly pan, it needs to be able to listen to touchmove events. If an element containing a Leaflet map has had disableBodyScroll() applied, panning becomes temperamental.

This is an issue for all elements which handle touchmove events, but do not necessarily scroll up & down (for instance, <input type="range"> is also affected).

Disabling Body Scroll on 'touchstart'

Hi,

I am looking to implement this when using the 'touchstart' rather than click.

Is this currently supported? As it doesn't seem to work for me on iOS Mobile Safari?

(iPad/Android seems to be ok in this case)

Kind regards,

Tom

iOS and Iframes

On iOS, if you disableBodyScroll(iframe) and scroll on the iframe, the body will still scroll and the iframe won't.

Lock scrolling of parent modal

Hello,

as I understand it, it's only possible to add a scroll lock to the body.
We have a situation where there is a child modal so I would like to lock it's parent instead of the body (being already locked at that point)

What I do in our own (not working on ios) code is search for an optional parentNode with queryselector and lock/release either that one or the body.

Would this be possible in your current setup and are you interested in a pull request on this issue?

How to enable scrollability for a target element?

<div id="wrapper">
    <Header/>
    <div id="content">
       content here.......
       <div id="modal">
         scrollable modal content here....
       </div>   
    </div>
    <Footer />
</div>

When the modal is open I disable body scroll for the content like so,
disableBodyScroll(document.querySelector('#content'));

But this disables the modal scrollability only on iOS. Is there a solution for this?

Does not work well with horizontal scroll in iOS Safari

When body scroll is locked, target element with horizontal scroll is scrolled very jerky, it's frozen at random moments. There is no such issue in Chrome.
I tried with your demo, just changed the width of target element and its child.

Multiple targetElements

I'm attempting to select a few targetElements which can be scrollable when disableBodyScroll is enabled.

A few tests below and for some reason when I have either more than one class/ID either stated in the const or in the DOM, it no longer allows scrolling in those sections.

const targetElement = document.querySelector('.test');
const targetElement = document.querySelectorAll('.test');
const targetElement = document.querySelectorAll('nav.large, nav.small, nav.enquiries');
const targetElement = document.querySelectorAll('#navLarge, #navSmall, #navEnquiries');

bodyScrollLock.disableBodyScroll(targetElement);

If I select just one element then it works fine but in my case I need to set a few (rather than having to create a different const for every modal/popup etc).

Working on iOS with Cordova + Vue.js?

This doesn't seem to work in a Cordova + Vue.js environment, while running on iOS. When I run in a browser (FF), it works fine, but on iOS, there is no effect at all.

Any ideas?

window reference introduced in 2.5.8 crashes Node

Hi, and thanks for this lib!

The reference to window introduced in #45 crashes Node when e.g. server rendering. Yes, it could be avoided by dynamically importing body-scroll-lock only on browser, but I believe it would make sense to just guard against this with a typeof window check or something similar.

I could make a PR next week. I guess it doesn't matter which result the passive event listener feature check gives when running on Node?

Problem on v2.5.8

In v2.5.8, I got a error on IE11.
Loading with Common JS seems to load the ESM file es/bodyScrollLock.js.

(Related #44 )

Thanks.

iOS 9 don't scroll within the overlay

Hey there, I stumbled upon an issue while testing body-scroll-lock.

It works well with iOS 10+ but when I test it on iOS 9 (I didn't test on other older versions), the body in the background doesn't scroll but neither is the content of my overlay, which is problematic.
You can see it on your demo page as well.

I don't know if it's possible to fix or not, but if not wouldn't it be better to just not applying the script at all? I mean, unscrollable content seems worst to me than background body scrolling.

Implementation does not reserve the scrollbar width

Thank you for this easy to use library.
Unfortunately, it doesn't quite fit our application.
The content of our site is centered. If the user opens a popup and we execute "disableBodyScroll", the scrollbar is removed. This makes the body slightly wider than before and the centered elements in the background jump to the right.

In this case it would make sense to reserve the space for the scrollbar. Could the following solution, possibly optional, fit to the library? Then I would create a PullRequest.

var setOverflowHidden = function setOverflowHidden() {
  // Setting overflow on body/documentElement synchronously in Desktop Safari slows down
  // the responsiveness for some reason. Setting within a setTimeout fixes this.
  setTimeout(function () {
    var padding = window.innerWidth - document.body.clientWidth;
    document.body.style.paddingRight = padding + 'px';
    document.body.style.overflow = 'hidden';
    document.documentElement.style.overflow = 'hidden';
  });
};

var setOverflowAuto = function setOverflowAuto() {
  // Setting overflow on body/documentElement synchronously in Desktop Safari slows down
  // the responsiveness for some reason. Setting within a setTimeout fixes this.
  setTimeout(function () {
    document.body.style.paddingRight = 0;
    document.body.style.overflow = 'auto';
    document.documentElement.style.overflow = 'auto';
  });
};

Does not work with Firefox Focus on Android

Firefox Focus seems to have the same behavior as iOS. isIosDevice isn't true since it is on Android, thus you can still scroll. Need to add a user agent check for firefox focus.

Momentum scrolling does not work on iOS

I'm using create-react-app and have called disableBodyScroll on document.querySelector('#root'). Where root has style="height: 100vh; width: 100vw; overflow: auto;". This does seem to work well on Android and Desktop. It also resolves the issue on iOS with the background image scrolling with the content.

My issue is that when a scrolling action has begun and is released, scrolling comes to a dead stop on iOS. I would expect to see some 'momentum' in the scroll.

The only iOS device I've been able to test on is an iPhone 6s running iOS 12.0.

NPM version 6.4.1, NodeJS version 8.11.3

targetElement should be optional

I don't agree with the current behavior (at least in iOS simulator) where disableBodyScroll does not work if you don't provide a targetElement

It should either:

  1. Error when a targetElement is not provided, warning the developer that one is required
  2. (better): Allow a null targetElement, wherein everything is prevented from scrolling.

DOes not work in latest ios

Hi
This does not seems to work in Iphone safari - latest ios.
We have a similar code and it seems to have the same issue.
When I try this on my laptop it works without any issue and so does my code but in iOS it does not seem to work.
Kind Regards
Sandeep

Does this work for iframes?

I am trying to use your package for an iframe overlay and it doesn't seem to work. The body is still scrollable even after calling bodyScrollLock.disableBodyScroll(iframe) with the iframe as the target.

Am I missing anything? I can provide a repro

The script tab cannot be self-closing

The README here, and on npmjs both tell the user to include the script using a self-closing tag:

You can now also load via a <script src='lib/bodyScrollLock.js /> tag (refer to the lib folder).

This doesn't work, and should be <script src=...></script>.

Demo Not working on Chrome for iOS

When I was testing the demo site in Chrome for iOS it appears body scroll lock has no effect.

Tested Devices:
iPhone 8 iOS 11.1 Chrome
iPhone 6 iOS 10 Chrome
iPhone 6S Plus iOS 9 Chrome

Is this still working?

I just tried the demo today and is not working on iOS Safari, iOS Chrome, and iOS Firefox.

Am I missing something?

Ship module version

I'm using native es modules, which are supported by all modern browsers now. Is it possible to publish an es module version of your code. So basically your source code without the type annotations. :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.