React event onMouseLeave Non déclenché lorsque le curseur se déplace rapidement
J'essaie de mettre en oeuvre l'événement de vol stationnaire mais onMouseLeave n'est pas toujours déclenché en quittant l'élément surtout quand le curseur se déplace rapidement sur les éléments. J'ai essayé I Chrome, Firefox et Internet Explorer mais dans chaque navigateur le même problème est apparu.
mon 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;
2 réponses
semble être un problème causé par la délégation d'événement lorsque l'écouteur d'événement est sur l'élément parent et que les éléments enfants sont ajoutés/supprimés conditionnellement du DOM. mettre un composant" hover target " qui se trouve au-dessus de tout devrait faire en sorte que cela fonctionne correctement, mais pourrait causer d'autres problèmes si vous devez cliquer sur des éléments à l'intérieur.
<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 });
}
}
j'ai eu un problème similaire, j'ai essayé différentes approches et j'ai réglé sur cette solution de contournement (en s'appuyant en partie sur jQuery):
- Appel
$(event.currentTarget).one("mouseleave", this.onMouseLeaveHandler.bind(this));
quand onMouseEnter est trigger. - ne pas mettre de gestionnaire d'événements onMouseLeave.
Voici un exemple:
import React from 'react';
import $ from 'jquery';
import Autolinker from 'autolinker';
import DateTime from './DateTime.jsx'
class Comment extends React.Component{
constructor(props){
super(props);
this.state = {
hovering: false
};
}
render(){
return <li className="media comment" onMouseEnter={this.handleOnMouseOver.bind(this)}>
<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});
$(event.currentTarget).one("mouseleave", this.onMouseLeaveHandler.bind(this));
}
handleOnMouseOut(event){
event.preventDefault();
this.setState({hovering:false});
}
newlines(text) {
if (text)
return text.replace(/\n/g, '<br />');
}
}
export default Comment;
Ou vérifier cet exemple sur jsfiddle: http://jsfiddle.net/qtbr5cg6/1/