First, thank you very much for writing this component. I've tried many different custom scrollbar components but this is the first one that I literally just dropped into my code and it worked flawlessly. Plus the default styling happens to be exactly what I was going for. Saved me tons of time and is definitely appreciated.
One thing that I'm trying to do is prevent scrolling on a div from causing the entire document to scroll when you get to the top or bottom of the div. I thought I could cancel the scroll event from the onScroll handler but it doesn't seem to work. I looked at the code and it's not clear to me why it wouldn't.
Here's my code:
handleScroll(e, values) {
if (values.top === 0 || values.top === 1) {
e.stopImmediatePropagation();
e.preventDefault();
e.returnValue = false;
return false;
}
}
render() {
let { children } = this.props;
let scrollerStyle = {height: 400px, width: 'auto'};
return (
<Scrollbars
style={scrollerStyle}
onScroll={this.handleScroll.bind(this)}>
{children}
</Scrollbars>
);
}
Hey bunkat, the component uses the native browser scrolling (the native scrollbars are just hidden). I think the described behaviour is the browser's default. If I got you right, you don't want the document to scroll when the mouse is over your component and it has reached it's own top (or bottom).
I would have thought that this would be possible with event.stopPropagation() but maybe you could get it to work like this:
class MyScrollbars extends Component {
handleScroll(e, values) {
this.setState(values);
}
handleDocumentScroll(e) {
const { top } = this.state;
if (top <= 1) e.preventDefault()
}
componentDidMount() {
document.addEventListener('scroll', this.handleDocumentScroll.bind(null, this);
}
render() {
return (
<Scrollbars
onScroll={this.handleScroll.bind(null, this)}>
{this.props.children}
</Scrollbars>
);
}
}
(this.setState could have cause multiple renders; if you want to, you can store the value directy on the component with this._top = values.top and then in handleDocumentScroll if (this._top <= 1))
the above code is not working, this code will work
handleScroll(e, values) {
var scrollarea = this.refs.container.parentNode;
var dir = (e.detail<0) ? 1 : (e.wheelDelta>0) ? 1 : -1;
if ((dir == 1 && scrollarea.scrollTop == 0) || (dir == -1 && scrollarea.scrollTop == scrollarea.scrollHeight-scrollarea.clientHeight)){
e.preventDefault();
}
}
componentDidMount() {
this.refs.container.parentNode.addEventListener('scroll', this.handleScroll);
this.refs.container.parentNode.addEventListener('wheel', this.handleScroll);
}
componentWillUnmount(){
this.refs.container.parentNode.removeEventListener('scroll', this.handleScroll);
this.refs.container.parentNode.removeEventListener('wheel', this.handleScroll);
}
render() {
return (
<Scrollbars>
<div ref="container">
</div>
</Scrollbars>
);
}
Thx @mrwnmonm. I'll close this then.
@mrwnmonm it's method doesn't work on mobile( why?
Most helpful comment
the above code is not working, this code will work