2

Is it possible to register onScroll event on a react element which does not have scrollbar / overflow ?

I wish to create zoom on a picture with mouse wheel scrolling. I tried

<div style={{position: "relative", width: "100%", height:"100%"}} onScroll={ () => console.log("TEST")}>

this wont fire event, neither will onWheel. If I change event to onClick everything works.

I know it's possbile, because there is a React components which make it work, I tried react wheel handler and it works. But how do they make it register mouse wheel events when there is no overflow or scrollbars?

EDIT:

I got it to work when I manually added eventlistener to componentDidMount, this is my current component. Is there a way I could make synthetic event onWheel work? I tried to add onWheel to div's and img but it wont fire.

class Zoom extends Component {
    state = {
      size: 20,      
    }

    componentDidMount() {
       window.addEventListener('wheel', this.handleScroll, true);
    }
    
    handleScroll = e => {
        e.preventDefault();  
        console.log(e)
        if (e.deltaY > 0 && this.state.size < 50) {
            this.setState({size: this.state.size + 1})
        } else if (e.deltaY < 0 && this.state.size > 20) {
            this.setState({size: this.state.size - 1})
        }       
      }
 
    render = () =>

    <div className="livetods-product-image-container" style={{
        top: openAsModal() ? '25%' : '20%',
        left: openAsModal() ? '30%' : '',
        right: openAsModal() ? '30%' : '',
        width: this.state.size + "%"        
    }}>

    <div className="livetods-product-image-button-container" >
                <div></div>             
                <h6 className="livetods-product-image-name">{this.props.name}</h6>
                <span className="livetods-modal-header-close-button" onClick={e => this.props.hideImage()}>&times;</span>   

    </div>

    <div style={{position: "relative", width: "100%", height:"100%"}}>

        <div style={{position: "absolute", padding: "5px"}}>
            <FontAwesomeIcon icon={faSearchPlus} color={'red'} style={{ width: '20px', height: '20px', pointerEvents:"none"}}/>
        </div>
        
            <img src={this.props.src} style={{borderRadius: "5px"}}/>      
       
    </div>

</div>
    
}
Jeekim
  • 543
  • 5
  • 15

1 Answers1

2

Use the onWheel event and its properties instead of onScroll to achieve the same result.

onScroll event no longer bubbles up in react. This question is pretty similar.

onWheel works for both trackpad scrolling as well as mouse wheel scrolling.

Here is a simple example that shows onWheel working with your provided code sample.

UPDATE:

I have changed the codesanbox example to reflect your class component. onWheel works in it too now. The issue you could be facing earlier was a warning like this one:

Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the method `isPropagationStopped` on a released/nullified synthetic event. This is a no-op function. If you must keep the original synthetic event around, use event.persist(). See https://reactjs.org/docs/legacy-event-pooling.html for more information.

The workaround to which is adding e.persist() to your onScroll function, as shown in my example.

Karan Sapolia
  • 640
  • 9
  • 18
  • It still didnt work for me, I did get it to fire when I manually added eventlistener like so componentDidMount() { window.addEventListener('wheel', this.handleScroll, true); } – Jeekim Jun 15 '21 at 18:59
  • If needed, you could edit the question and share the whole component where you are trying to implement it, and we could help you set the listener up from within React's synthetic events for your class component. Otherwise, you could just mark/upvote my answer if it was helpful. – Karan Sapolia Jun 15 '21 at 20:27
  • Thank you for taking time to answer! I updated original post with component code. It is working now with manually adding event listener. It would be great if I could make synthetic event work. – Jeekim Jun 16 '21 at 04:27
  • Have updated the answer. Hope this solves your issue. – Karan Sapolia Jun 16 '21 at 09:41