3

TL;DR:

See my jsfiddle link where scrolling child div up till bottom/top should not start scrolling parent. I tried using e.stopPropagation() which didn't work. So need solution (without using mixins).

My Code:

http://jsfiddle.net/vmvrphjn/

//////////HTML CODE
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

////////CSS CODE    
.childScroll{
  max-height: 200px;
  overflow-y: scroll;
  background-color: white;
  max-width: 200px;
  margin: 0 auto;
  border: 1px solid blue
}

.parentScroll {
  text-align: center;
  max-height: 300px;
  overflow-y: scroll;
  background-color: lightgreen;
  padding: 10px;
}

////////JS CODE 
class Hello extends React.Component {
  render() {

    return (
    <div className='parentScroll'>
          Scrollable Parent: <br /><br />
        <div className='childScroll' onWheel = {(e)=>{console.log('Scrolling Me..'); e.stopPropagation();}}>
      Scroll CHILD LIST:1 <br /><br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        Some text blah<br />
        </div>
    <div className='childScroll' onWheel = {(e)=>{console.log('Parent got scroll event');}}>
      Scroll CHILD LIST:2 <br /><br />
        Hi text blah<br />
        Hi text blah<br />
        Hi text blah<br />
        Hi text blah<br />
        Hi text blah<br />
        Hi text blah<br />
        Hi text blah<br />
        Hi text blah<br />
        Hi text blah<br />
        Hi text blah<br />
    </div>
  </div>
);
  }
}

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

My Target:

I am having a div which scrolls. But on coming to the top or the bottom after the scrolling the div, the scrolling starts happening on the entire page itself which I don't want. I think it's happening due to event propagation, so I am trying to stop in following manner.

My Implementation:

I am using "extends Component (es6 way)" to create my components. And I've put onWheel event listener as

It's consoling out 'Scrolling Me' fine but I am not able to stop propagating this event to the parent. Not sure why stopPropagation is not happening exactly or whether this issue is happening because of propagation

I don't want to use libraries which used mixins, so please don't suggest me this way.

master_dodo
  • 1,203
  • 3
  • 20
  • 31

2 Answers2

4

I resolved the issue using following ways.

EARLIER SOLUTION:

const rdom = require('react-dom');  

<div onMouseOver={() => {
      const ele = rdom.findDOMNode(this);
      if (ele.scrollTop === 0 && ele.scrollHeight === ele.clientHeight) {
           return;
         } else {
           document.body.style.overflow = 'hidden';
         }
     }}
     onMouseOut={() => {
      document.body.style.overflow = 'auto';
     }}
</div>

NEW SOLUTION: (Since Mac and Linux operates scroll bars differently than windows, the above solution is annoying as it removes and add scroll bar to the document thus reducing/increasing its width which can shake other elements)

handleScroll(e) {

const ele = rdom.findDOMNode(this);

if (e.nativeEvent.deltaY <= 0) {
  /* scrolling up */
  if(ele.scrollTop <= 0) {e.preventDefault();}
} 
else
{
  /* scrolling down */
  if(ele.scrollTop + ele.clientHeight >= ele.scrollHeight) {
    e.preventDefault();
  }
}


/*Look question for the placement of below CODE*/
onWheel={(e) => {this.handleScroll(e);}}

ANOTHER SOLUTION:

You can also find the if document/window/body has been scrolled uptil your scrollable div. And then make this scrollable div as position: fixed. Fixed property automatically doesn't let the document/window/body get that onWheel event.

master_dodo
  • 1,203
  • 3
  • 20
  • 31
1

I don't have enough reputation to comment, but check the solution here:

Scrolling child div scrolls the window, how do I stop that?

$.fn.scrollGuard2 = function() {
 return this
  .on( 'wheel', function ( e ) {
   var $this = $(this);
   if (e.originalEvent.deltaY < 0) {
     /* scrolling up */
     return ($this.scrollTop() > 0);
   } else {
     /* scrolling down */
     return ($this.scrollTop() + $this.innerHeight() < $this[0].scrollHeight);
   }
  });
};  

demo'ed: http://jsfiddle.net/3dxpyjoz/10/

Community
  • 1
  • 1
reddiky
  • 172
  • 2
  • 11
  • I came across similar/same solution before but on this demo while scrolling down it kind of bounce back abruptly when trying to scroll more than it's height. Not sure why!. Anyways, since, I am doing react's way, I couldn't make it work earlier. But your answer motivated to do again and it worked. Thanks :) I'm also adding answer. – master_dodo Feb 27 '16 at 19:28