React: Событие onMouseLeave не срабатывает при быстром движении курсора
Проблема с событием hover в React: onMouseLeave не всегда срабатывает
Я пытаюсь реализовать событие hover
, но 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;
Описание проблемы:
Несмотря на то, что события onMouseEnter
и onMouseLeave
должны работать корректно, я замечаю, что в случае быстрого перемещения курсора событие onMouseLeave
не всегда срабатывает. Это приводит к тому, что состояние hovering
не обновляется корректно, и элементы интерфейса не отображаются так, как ожидалось.
Есть ли известные проблемы с этими событиями в React? Как можно решить эту проблему?
3 ответ(ов)
Похоже, что проблема вызвана делегированием событий, когда обработчик событий находится на родительском элементе, а дочерние элементы условно добавляются или удаляются из DOM. Введение компонента "hover target", который располагается поверх остальных элементов, должно исправить эту проблему, но может привести к другим сложностям, если вам нужно будет кликать на элементы внутри.
<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 });
}
}
Проблема заключается в том, что при добавлении или удалении дочерних элементов события на родительском элементе могут не срабатывать, так как целевой элемент для события может быть не в DOM в момент его срабатывания. Использование "hover target" может помочь, но вы должны быть осторожны, чтобы это не повлияло на взаимодействие с другими элементами. Если при использовании такого подхода вам потребуется обрабатывать клики по дочерним элементам, вам может понадобиться добавить дополнительные обработчики событий или изменить структуру компонента.
У меня была аналогичная проблема на днях. В моем случае я изменил события.
- Заменил
onMouseEnter
наonMouseOver
. - Заменил
onMouseLeave
наonMouseOut
.
Я решил эту проблему, изменив следующие события:
- Заменил
onMouseEnter
наonPointerEnter
. - Заменил
onMouseLeave
наonPointerLeave
.
Это помогло обеспечить лучшую совместимость с сенсорными экранами и улучшить взаимодействие с пользователем.
Как реализовать дебаунс?
Обнаружена ошибка: Невозможное нарушение: Неверный тип элемента: ожидался строковый тип (для встроенных компонентов) или класс/функция, но получен объект
Добавление тега script в React/JSX
React + Redux — Замедление работы onChange в Input при вводе, когда значение берется из состояния
Установить значение по умолчанию в выпадающем списке с помощью jQuery