专栏名称: 牧羊童鞋
你应该了解真相,真想能够使你自由
目录
相关文章推荐
掌上平度  ·  人气火爆!平度旅游迎来开门红! ·  23 小时前  
重庆市文化和旅游发展委员会  ·  热!辣!滚!烫!春节假期全市累计接待国内游客 ... ·  2 天前  
广西旅游发展委员会  ·  2025年春节假期国内出游5.01亿人次 ·  2 天前  
四川高院  ·  过年的法官在哪里?峨眉金顶等着你 ·  3 天前  
福州日报  ·  春节这八天,福州成“顶流”! ·  3 天前  
福州日报  ·  春节这八天,福州成“顶流”! ·  3 天前  
51好读  ›  专栏  ›  牧羊童鞋

react事件机制和原生dom事件机制之男女有别

牧羊童鞋  · 简书  ·  · 2017-12-08 15:13

正文

今天遇到这么一个问题:

我们在实现列表拖拽排序时使用了 react-sortable-hoc 这个库,确实很好用,利用ES装饰器新特性,几个@符号就解决了。但是因为我们在每一个列表item上还有菜单按钮,点击菜单按钮会弹出菜单,这样一来就会发现菜单的click事件和 react-sortable-hoc mousedown 事件冲突了,特别是在你把pressDelay设置低于300ms时。

如果你使用过这个组件,你会发现pressDelay超过100ms,拖住体验就不再有丝滑般的感觉了。怎么办?我们需要完美啊,既要丝滑般的感觉又不要事件冲突。

假设在jQuery一把鎍的时代,这个都不是问题,因为菜单按键和列表item明显是父子元素的关系,我只需要把菜单上的mouse事件不向父元素listitem冒泡就解决了。

事实上时代并没有变化,react时代也是这么解决的。只是解决的时候会发现一个细节需要注意,那就是-- react事件机制和原生dom事件机制之男女有别

我们先来看 react-sortable-hoc 组件源码里是怎么绑定事件的

_utils.events.move.forEach(function (eventName) {
  // 原生事件addEventListener
   return _this.listenerNode.addEventListener(eventName, 
   _this.handleSortMove, false);
});
_utils.events.end.forEach(function (eventName) {
  return _this.listenerNode.addEventListener(eventName, _this.handleSortEnd, false);
});

使用的是dom的addEventListener函数绑定事件,这走的是原生事件机制。

然后看我们在react项目中怎么去stop冒泡的

// 简单期间,只贴render函数足以 
render() {
    const { showMenu } = this.state;
    const { children, className } = this.props;
    const cls = classNames(styles['dropdown'], className);
    return (
      <div
        className={cls}
        ref={(el) => {
          this.dropDown = el;
        }}
        { // 这里直接绑定onMouseDown,走的是react的SyntheticEvent机制 }
        onMouseDown={ (e) => e.stopPropagation()} 
      >
        { this.renderDropIcon() }
        <Animate transitionName='fade' component='span'>
          { showMenu && this.renderDropDownMenu()}
        </Animate>
      </div>
    );
  }

在jsx模板里直接绑定onMouseDown/onMouseMove/onMouseUp事件,并调用 e.stopPropagation() 企图阻止冒泡。

然后你就发现完全没卵用啊,没道理啊,怎么会没有用呢?抓耳中...

这时候如果你在两个地方均加上log,你会发现竟然是 react-sortable-hoc 包裹的列表item的 mousedown 事件先触发,作为子元素的菜单后触发,更郁闷了有么有?

其实你通过本文的题目应该就猜到原因了。根本原因就是react的事件机制自成一套,具体可以看这篇文章 React事件机制
]( https://segmentfault.com/a/1190000008782645 )







请到「今天看啥」查看全文


推荐文章
掌上平度  ·  人气火爆!平度旅游迎来开门红!
23 小时前
重庆市文化和旅游发展委员会  ·  热!辣!滚!烫!春节假期全市累计接待国内游客3316.16万人次!
2 天前
广西旅游发展委员会  ·  2025年春节假期国内出游5.01亿人次
2 天前
福州日报  ·  春节这八天,福州成“顶流”!
3 天前
福州日报  ·  春节这八天,福州成“顶流”!
3 天前
张德芬空间  ·  总要一个人,走过一些艰辛
7 年前
TimeOut北京  ·  北京文化镖局丨画说北京话
7 年前
复利人生  ·  下周策略及短线热点分析
7 年前