jossmac / react-scrolllock Goto Github PK
View Code? Open in Web Editor NEW๐ Prevent scroll on the <body />
Home Page: https://jossmac.github.io/react-scrolllock
License: MIT License
๐ Prevent scroll on the <body />
Home Page: https://jossmac.github.io/react-scrolllock
License: MIT License
There's a delay after loading the page before isActive
is loaded. I set the isActive
with a state called isLoading
which is default as true but the scroll is not locked when the page loads but it is locked after about 500ms. In this code, while Dimmer
is already active, ScrollLock is not
<ScrollLock isActive={props.isLoading} />
<Dimmer active={props.isLoading}>
<Loader>Loading</Loader>
</Dimmer>```
Looks like this library uses findDOMNode
internally.
This is now deprecated in React and throws a warning when running in StrictMode: https://reactjs.org/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage
Due to this recent commit:
99f54ed
The defaultProps prop is being defined incorrectly and therefore
if (this.props.preventContentJumping) {
will evaluate to undefined/false and content will shift instead of defaulting to not shifting.
Something like this in a react-scrolllock.d.ts
file would be awesome to use this hin TypeScript :)
declare module 'react-scrolllock' {
export interface Props {
touchScrollTarget?: HTMLElement;
accountForScrollbars?: boolean;
}
const Component: React.ComponentClass<Props>;
export default Component;
}
Given the recent breakage in v2 that could've been caught by using the test suite as a gate keeper, would you be interested in setting up something like TravisCI and or semantic-release. I'd be happy to put together a PR for the plumbing but would require you to setup the auth tokens in the right places.
We have a dependency on your library, so setting up some automation around tests and publishing would be in our best interests too.
Let me know if you're interested.
I have a simple idea to reduce the code size and improve maintainability:
const bodyStyle = document.createElement("style");
document.head.appendChild(style);
style.sheet.insertRule('body.react-scrolllock { overflow: hidden !important }');
This way you wouldn't have to track the original styles of the body
element and you could just toggle the class and/or remove the stylesheet from document.
Also a new maintainer/developer would find out the source of overflow hidden
.
If you render 2 or more ScrollLock components, you end up with a permanently locked body, even unmounting them.
Here a codesandbox example: https://codesandbox.io/s/q2l94npn9
When putting the element on my page in any form, the following errors call:
this.scrollableArea.addEventListener is not a function
this.scrollableArea.removeEventListener is not a function
I'm using it as the docs suggest, in a modal component:
<div>
<TouchScrollable>
<View>
{p.children}
</View>
/TouchScrollable>
</div>
What I'm trying to achieve: currently the scroll lock works great on standard web by just including when necessary on my root screen. As suggested by the docs, it's not playing well on mobile - even the modals become locked from touch scrolling.
Update: seems like the error only occurs when you use a custom child component (i.e. View) - div doesn't cause the error. However, touch scrolling is still locked in the modal when it shouldn't be (standard mouse scrolling in Chrome simulator, and on desktop browsers, still works fine).
If we have an element with horizontal scrolling, it is possible to force TouchScrollable to scroll an element only by forcing not only the width limit, but also the height limit, in which the nested block must be at least 1 pixel more, then it works.
Hi!
I am using the 5.0.0
version but getting an error:
Uncaught TypeError: Cannot read property 'addEventListener' of undefined
at TouchScrollable.componentDidMount (TouchScrollable.js:50)
This code seems to be breaking:
_createClass(TouchScrollable, [{
key: 'componentDidMount',
value: function componentDidMount() {
if (!_exenv.canUseEventListeners) return;
// Breaking line
this.scrollableArea.addEventListener('touchstart', _utils.preventInertiaScroll, _utils.listenerOptions);
this.scrollableArea.addEventListener('touchmove', _utils.allowTouchMove, _utils.listenerOptions);
}
This was my original piece of code. Every time isOpen
was set to true, I was getting the error above.
import ScrollLock from 'react-scrolllock';
function Sidebar(...) {
// ...
return (
<MobileSidebar>
<ScrollLock isActive={isOpen}>{children}</ScrollLock>
<MobileSidebar/>
);
}
Am I doing something wrong here? ๐ค
I fixed it the following way, but was wondering if I was misusing it.
import ScrollLock from 'react-scrolllock';
function Sidebar(...) {
// ...
return (
<MobileSidebar>
{isOpen && <ScrollLock />}
{children}
<MobileSidebar/>
);
}
Thanks a lot ๐ !
Hi, I can't find any changelog in the repo, and the releases tab doesn't show anything.
Is there a CHANGELOG published anywhere as to what differs between different versions?
Hi Joss, first of all, thanks for your hard work on this lib!
I've run into a few issues with SSR when using the lib, which appear to be coming from the utility functions:
I was able to alleviate the issues locally by checking for typeof window
wherever a util fn was checking for document
or window
like such:
function getPadding() {
if (typeof window === 'undefined' || !window || !document) return 0;
...
}
function getDocumentHeight() {
if (typeof window !== 'undefined' && document && document.body) {
...
}
// these fns also check for window but weren't giving me any issues at the time
function isTouchDevice() {...}
function getWindowHeight() {...}
I haven't run into any problems with the above, but I realize it may not be all encompassing or I may be missing something. I'm happy to help with anything, so if you need me to make any changes or want me to make a PR, just let me know!
Thanks,
-Marc
Hi! When will support for React 17.x be added? ๐
You made a big change but only bumped minor version, so our project that relies on this library stopped working by itself because it updated library.
As a workaround, we forced older version using package.json
/app/node_modules/react-scrolllock/dist/PropertyToggle.js:25
var defaultTarget = document.body;
^
ReferenceError: document is not defined
at Object.<anonymous> (/app/node_modules/react-scrolllock/dist/PropertyToggle.js:25:21)
at Module._compile (module.js:660:30)
at Object.Module._extensions..js (module.js:671:10)
at Module.load (module.js:573:32)
at tryModuleLoad (module.js:513:12)
at Function.Module._load (module.js:505:3)
at Module.require (module.js:604:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/app/node_modules/react-scrolllock/dist/ScrollLock.js:17:23)
at Module._compile (module.js:660:30)
error: Forever detected script exited with code: 1
Sometimes it's the HTML element that needs to be scroll locked? It'd be great it there was a simple option to select it instead of body.
Since they move between being direct descendants of ScrollLock, and children of SheetLock:
https://github.com/jossmac/react-scrolllock/blob/master/src/ScrollLock.js#L52
This is bad for performance and breaks state and transitions.
npm install [email protected] not lib file
src/ScrollLock.js needs a simple fix according to https://facebook.github.io/react/blog/2017/04/07/react-v15.5.0.html
For some reason the body locks as intended. But the page scrolls to the top and locks, not like in the demo where the body locks wherever the current scroll position is.
Im using the Gatsby frontend framework, has anybody experienced this issue?
I've been using it on production for a month now and noticed <TouchScrollable>
don't work on iOS 9 and below. Not only on my pages, but on your demo too, as far as I could test on BrowserStack.
https://jossmac.github.io/react-scrolllock
Is it a known issue? Glad to help with a PR if there's any clue on where this issue might be.
The title.
Using hooks in my project, but react-scrolllock doesn't work.
Hi,
This is great but is it possible to use along with translateX?
I have a mobile menu that slides in from the right however that no longer works when using react-scrolllock. Instead it just immediately appears when toggling the menu.
Thanks!
To make it work on desktop Safari need to set overflow: hidden, not overflow Y
. Perhaps, do both?
https://codesandbox.io/s/hungry-stallman-elqtm?file=/src/App.js
Caught this in a test when implementing TouchScrollable for mobile. Just needs some checks when binding the handlers. Will try to submit a PR if I have some time.
I was recently building a modal and using ScrollLock and I inadvertently introduced a bug that cost me 30 minutes or so simply by wrapping a div
that had a critical ref
in a ScrollLock
component. It turns out that TouchScrollable
clobbers the ref
prop:
react-scrolllock/src/TouchScrollable.js
Lines 50 to 53 in 90cbf33
There are workarounds for this (like using React.forwardRef
), but at the very least this behavior should be documented.
when TouchScrollable element has scroll, onTouchStart and onTouchEnd events work,
but onTouchMove don't work
<div id="wrapper">
<Header/>
<div id="content">
content here.......
<div id="modal">
scrollable modal content here....
</div>
</div>
{modalOpen &&
<ScrollLock />
}
<Footer />
</div>
When the modal is open I want to disable body scroll for the content. But what happens is even the modal rmains locked only on iOS
.
Here's a demo to get an idea about my usecase.
https://github.com/tharakabimal/body-scroll-lock
Tested on an iPhone 5S
, iOS version 11.3.1
Anyone having an issue with touchmove events on inputs in a scrollable area causing the body to scroll while the body is locked?
Hello, first, thank you for this wonderful library.
Please see the following code without scrolllock.
class App extends Component {
constructor(props) {
super(props);
this.ref = React.createRef();
}
render() {
console.log(this.ref.current); // this will be null, no second render because niether state nor props changed
return <div ref={this.ref} someprop={this.ref.current} />; // someprop gets null
}
}
A way to workaround will be like this
class App extends Component {
constructor(props) {
super(props);
this.state = { ref: null }
this.ref = React.createRef();
}
componentDidMount() {
this.setState({ ref: this.ref.current })
}
render() {
return <div ref={this.ref} someprop={this.state.ref.current} />; // someprop gets null first, and actual dom second
}
}
However, this won't work with touchScrollTarget prop
class App extends Component {
constructor(props) {
super(props);
this.state = { ref: null }
this.ref = React.createRef();
}
componentDidMount() {
this.setState({ ref: this.ref.current })
}
render() {
return (
<div>
<div ref={this.ref} />
<ScrollLock touchScrollTarget={this.state.ref.current} /> // this is not working
</div>
)
}
}
You will have to do this
class App extends Component {
constructor(props) {
super(props);
this.state = { ref: null }
this.ref = React.createRef();
}
componentDidMount() {
this.setState({ ref: this.ref.current })
}
render() {
return (
<div>
<div ref={this.ref} />
<ScrollLock key={this.state.ref} touchScrollTarget={this.state.ref.current} /> // add key
</div>
)
}
}
add additional key to trigger componentDidMount twice.
The body is unscrollable but designated scrollable elements are unscrollable. Tested using both the ScrollLock
and TouchScrollable
components. The same behavior works on mobile Chrome and Safari (iOS 13)
FF version: 68.1.1.
Android version: 10 (QP1A.190711.020)
Phone model: Pixel 2
Migrating from the internal canUseDom
to the version from exenv
has resulted in ScrollLock
never mounting. This is due to the casing being different on the export from exenv
.
Renaming all usages of canUseDom
to canUseDOM
seems to fix the issue.
I'm not even sure if there is any (easy) solution, but I'll post this anyway.
It seems that touchScrollTarget
should be scrollable in order for touchmove
events not to propagate to the body. However, in our app we don't always know if the contents fits into scrollable container or not. If it does, touch events will scroll the touchScrollTarget
. However, in case it doesn't, they will scroll <body>
.
For example, in the example (which is also the home page), there is an area with overflow-y: auto
and fixed height. Removing height will make the page scrollable even when the lock is enabled.
{
componentWillMount() { ... }
}
is not ES5!!! It should be
{
componentWillMount: function() { ... }
}
Demo to reproduce:
Code: https://codesandbox.io/s/thirsty-ardinghelli-fsjl0
Demo: https://fsjl0.csb.app/
Reproduce using mobile emulator
In a range input the drag behavior is not working properly in mobile. It updates on clicks, but not on drag
Happens both for Chrome 83 and 81
[email protected] requires a peer of react@^0.14 || ^15.0 but none is installed. You must install peer dependencies yourself.
Thank you for you work. Unfortunately, as many other similar libraries this one does not lock body when scrolling inside iframe in iOS Safari. Here is an example: https://codesandbox.io/s/compassionate-frog-jnm7f?fontsize=14&hidenavigation=1&theme=dark&file=/src/App.js
Today I got a little bit of a pain debugging why touch scroll does not work within some overflowing inner components on the page that I want be scrollable when scroll is locked with presence of Scrollock.
Then I've found that I can pass a scrollTarget={myScrollableContainer} prop to Scrolllock to fix it. However that was through reading actual source code, not the README file, so probably it could be great if it's updated.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.