50

Im trying to implement hover event but onMouseLeave is not always triggering when leaving element especially when moving cursor over elements fast. I tried i Chrome, Firefox and Internet Explorer but in every browser same problem appeared.

My code:

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;
zazmaister
  • 667
  • 1
  • 7
  • 10
  • 1
    Hey, how are you determining onMouseLeave is not triggered? Have you tried adding console.log statements? I'm wondering if instead you are experiencing a bad ordering for onMouseOver/onMouseOut because the setting of states is not a synchronous action. I created a simple react component and I couldn't easily reproduce. – noveyak Aug 02 '15 at 19:26
  • It happen sometimes, that when leaving element onMouseLeave function is not called.. Yes i tried with logging and function is not being called.. then how should i implement hover event? – zazmaister Aug 02 '15 at 19:38
  • You could try onMouseOver/onMouseOut to see if it works better for you since I think these events are better supported although the behavior of this is slightly different so might not be suitable for your application. – noveyak Aug 02 '15 at 20:25
  • Please upload a JSFiddle to understand your problem. I could not find anything wrong in your code. Also, using mouseout is discouraged as it works way different when there are children elements. You can see the difference in jQuery's docs (although you are not using jQuery, the behavior is mostly the same): https://api.jquery.com/mouseleave/ – damianmr Aug 03 '15 at 07:04
  • This is definitely happening to me too. I have both `onMouseOver` and `onMouseOut` and the `onMouseOut` does not trigger sometimes when I hover over the element very quickly. I console logged on both onMouseOut and onMouseOver and it's just no triggering. This seems like a React SyntheticEvent issue – Eudis Duran Feb 05 '16 at 17:53
  • 1
    Possible duplicate of [How do you Hover in ReactJS? - onMouseLeave not registered during fast hover over](http://stackoverflow.com/questions/29981236/how-do-you-hover-in-reactjs-onmouseleave-not-registered-during-fast-hover-ove) – Cory Danielson Jul 27 '16 at 18:01
  • Thanks @noveyak ! I solved it by using setState as a function. – AlexZvl Sep 04 '18 at 10:28
  • 2
    @Alexandr could you please provide more information? Thanks – David Casanellas Oct 02 '18 at 11:16

2 Answers2

18

seems to be an issue caused by event delegation when the event listener is on the parent element and child elements are being conditionally added/removed from the DOM. putting a "hover target" component that sits on top of everything should make this work properly, but could cause other issues if you need to click elements inside.

<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 });
  }
}
bzk
  • 306
  • 3
  • 6
1

I had the same problem these days. In my case, I changed the events.

  • Change onMouseEnter to onMouseOver.
  • Change onMouseLeave to onMouseOut.
Dhia Djobbi
  • 1,176
  • 2
  • 15
  • 35