【问题标题】:React JS: onWheel bubbling stopPropagation not workingReact JS:onWheel 冒泡 stopPropagation 不起作用
【发布时间】:2016-01-14 13:32:12
【问题描述】:

TL;DR:

查看我的 jsfiddle 链接,其中将子 div 向上滚动到底部/顶部不应开始滚动父级。我尝试使用 e.stopPropagation() 这没有用。所以需要解决方案(不使用 mixins)。

我的代码:

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')
);

我的目标:

我有一个滚动的 div。但是在滚动 div 后到达顶部或底部时,滚动开始发生在我不想要的整个页面本身上。我认为这是由于事件传播而发生的,所以我试图以下列方式停止。

我的实现:

我正在使用“扩展组件(es6 方式)”来创建我的组件。我把 onWheel 事件监听器设置为

“滚动我”很好,但我无法停止将此事件传播给父级。 不知道为什么 stopPropagation 没有完全发生,或者这个问题是否因为传播而发生

我不想使用使用 mixins 的库,所以请不要这样建议我。

【问题讨论】:

    标签: reactjs react-jsx


    【解决方案1】:

    我通过以下方式解决了这个问题。

    早期解决方案:

    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>
    

    新解决方案: (由于 Mac 和 Linux 操作滚动条的方式与 Windows 不同,因此上述解决方案很烦人,因为它会在文档中删除和添加滚动条,从而减少/增加其宽度,这可能会影响其他元素)

    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);}}
    

    另一种解决方案:

    您还可以找到文档/窗口/正文是否已向上滚动到您的可滚动 div。然后将这个可滚动的 div 设置为位置:固定。固定属性自动不会让文档/窗口/正文获取该 onWheel 事件。

    【讨论】:

    • Safari 不支持onWheel 事件:(
    • @BigMoney 2021 年
    【解决方案2】:

    我没有足够的声誉来发表评论,但请在此处查看解决方案:

    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);
       }
      });
    };  
    

    演示:http://jsfiddle.net/3dxpyjoz/10/

    【讨论】:

    • 我之前遇到过类似/相同的解决方案,但是在这个演示中,向下滚动时它会在尝试滚动超过其高度时突然反弹。不知道为什么!无论如何,既然,我正在做反应的方式,我不能让它更早地工作。但是你的回答有动力再做一次,它奏效了。谢谢 :) 我也在添加答案。
    猜你喜欢
    • 2011-02-13
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-16
    相关资源
    最近更新 更多