React事件onMouseLeave在快速移动光标时未触发。

50

我正在尝试实现悬停事件,但是当光标快速移动到其他元素时,onMouseLeave并不总是触发。我已经在Chrome、Firefox和Internet Explorer中尝试过,但在每个浏览器中都出现了同样的问题。

我的代码:

import React from 'react';
import Autolinker from 'autolinker';
import DateTime from './DateTime.jsx'
class Comment extends React.Component{

     constructor(props){
        super(props);
        this.handleOnMouseOver = this.handleOnMouseOver.bind(this);
        this.handleOnMouseOut = this.handleOnMouseOut.bind(this);
        this.state = {
            hovering: false
        };
    }

    render(){
        return <li className="media comment" onMouseEnter={this.handleOnMouseOver} onMouseLeave={this.handleOnMouseOut}>
            <div className="image">
                <img src={this.props.activity.user.avatar.small_url} width="42" height="42" />
            </div>
            <div className="body">
                {this.state.hovering ? null : <time className="pull-right"><DateTime timeInMiliseconds={this.props.activity.published_at} byDay={true}/></time>}
                <p>
                    <strong>
                        <span>{this.props.activity.user.full_name}</span>
                        {this.state.hovering ? <span className="edit-comment">Edit</span> : null}

                    </strong>
                </p>    
             </div>
        </li>;
    }


    handleOnMouseOver(event){
         event.preventDefault();
         this.setState({hovering:true});
    }

    handleOnMouseOut(event){
        event.preventDefault();
        this.setState({hovering:false});
    }

     newlines(text) {
        if (text) 
            return text.replace(/\n/g, '<br />');

    }



}

export default Comment;

1
嘿,你是怎么确定 onMouseLeave 没有被触发的?你尝试添加 console.log 语句了吗?我想知道是否是因为设置 state 不是同步操作,导致 onMouseOver/onMouseOut 的顺序出现问题。我创建了一个简单的 React 组件,但我无法轻松地复现。 - noveyak
有时候会出现这种情况,当鼠标离开元素时onMouseLeave函数没有被调用。是的,我尝试过记录日志,但函数并没有被调用。那么我应该如何实现悬停事件呢? - zazmaister
你可以尝试使用onMouseOver/onMouseOut来查看它是否更适合你,因为我认为这些事件得到了更好的支持,尽管其行为略有不同,可能不适用于你的应用程序。 - noveyak
2
@Alexandr,你能否提供更多的信息吗?谢谢。 - David Casanellas
显示剩余3条评论
2个回答

18

似乎是由事件委托导致的问题,当事件监听器在父元素上时,而子元素正在有条件地添加/删除DOM。放置一个“悬停目标”组件,位于所有内容的顶部应该可以使其正常工作,但如果需要点击内部元素,可能会引起其他问题。

<Container isOpen={this.state.isOpen}>
 <HoverTarget
  onMouseEnter={e => this.mouseOver(e)}
  onMouseLeave={e => this.mouseOut(e)}
 />
 <Content/>
</Container>



mouseOver(e) {
  if (!this.state.isOpen) {
    this.setState({ isOpen: true });
  }
}

1

最近我也遇到了同样的问题。

在我的情况下,我改变了事件:

  • onMouseEnter更改为onMouseOver
  • onMouseLeave更改为onMouseOut

3
但请记住,将鼠标悬停在子节点上将被视为“从父节点移出”。 - Vitalii Korsakov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接