6

My question is similiar to this How to prevent page scrolling when scrolling a DIV element? but I'm wondering if there is an approach with css and/or react that does not require jQuery.

I want to disable page scrolling on a mouseWheel event when the cursor is over one particular div. The div is a graph which zooms on a mouseWheel event, and is rendered by a React component.

I've tried e.preventDefault however chrome tells me

Unable to preventDefault inside passive event listener due to target being treated as passive

Can anyone help? Thanks in advance.

EDIT: Found a simple solution for anyone looking.

changeScroll(){ 
    let style = document.body.style.overflow 
    document.body.style.overflow = (style === 'hidden') ? 'auto':'hidden'
} 

<div 
    onMouseEnter={this.changeScroll} 
    onMouseLeave={this.changeScroll} /> 
    <ReactComponent/> 
</div>

BarefootDev
  • 326
  • 3
  • 9
  • Maybe this helps ? https://stackoverflow.com/questions/4770025/how-to-disable-scrolling-temporarily + a mouseEnter / mouseLeave event to the that has to handle this special case – Luciano Semerini Apr 04 '19 at 06:04
  • 1
    Thanks, I ended up with something similiar and pretty simple. ```changeScroll(){ let style = document.body.style.overflow document.body.style.overflow = (style === 'hidden') ? 'auto':'hidden' }``` ```
    ```
    – BarefootDev Apr 04 '19 at 06:33

1 Answers1

11

Thanks! I was looking for a current answer for managing it.

My ReactJS solution was to add and remove the event when onMouseEnter/Leave is detected. Additionally, with the use of passive, taken from this answer link.

Principal component:

<Wrapper
    onWheel={this.handleScroll}
    onMouseEnter={this.disableScroll}
    onMouseLeave={this.enableScroll}
> ...</Wrapper>

handleScroll():

public handleScroll = (event) => {
    if (event.deltaY > 0) {
      this.decreaseValue()
    } else {
      this.increaseValue()
    }
}

enableScroll():

public enableScroll = () => {
    document.removeEventListener('wheel', this.preventDefault, false)
}

disableScroll():

public disableScroll = () => {
    document.addEventListener('wheel', this.preventDefault, {
      passive: false,
    })
}

preventdefault():

public preventDefault(e: any) {
    e = e || window.event
    if (e.preventDefault) {
      e.preventDefault()
    }
    e.returnValue = false
  }
KarlDivad
  • 131
  • 1
  • 5
  • I tried several solutions. This was which better worked! Can implement in you code too and be happy! =) – Jose Henrique Jul 04 '20 at 03:49
  • How does `decreaseValue` and `increaseValue` look? – Ini Jun 21 '22 at 14:30
  • @Ini It depends on your use case, it's just for handling each scroll up and down internally. – KarlDivad Jun 21 '22 at 21:14
  • You would scroll manually there via setting a new value to `scrollLeft` for example right? – Ini Jun 22 '22 at 08:34
  • 1
    @Ini Indeed, you could use `scrollLeft`,`scrollTop`, or `scrollTo` or any other method. – KarlDivad Jun 22 '22 at 16:28
  • It would be nice if there would be some css similar to touch-action, but for wheel instead of touch... maybe wheel-action or so, because this would greatly simplify things :/ – Ini Jun 23 '22 at 18:48