0

React: Событие onMouseLeave не срабатывает при быстром движении курсора

12

Проблема с событием 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 ответ(ов)

0

Похоже, что проблема вызвана делегированием событий, когда обработчик событий находится на родительском элементе, а дочерние элементы условно добавляются или удаляются из 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" может помочь, но вы должны быть осторожны, чтобы это не повлияло на взаимодействие с другими элементами. Если при использовании такого подхода вам потребуется обрабатывать клики по дочерним элементам, вам может понадобиться добавить дополнительные обработчики событий или изменить структуру компонента.

0

У меня была аналогичная проблема на днях. В моем случае я изменил события.

  • Заменил onMouseEnter на onMouseOver.
  • Заменил onMouseLeave на onMouseOut.
0

Я решил эту проблему, изменив следующие события:

  • Заменил onMouseEnter на onPointerEnter.
  • Заменил onMouseLeave на onPointerLeave.

Это помогло обеспечить лучшую совместимость с сенсорными экранами и улучшить взаимодействие с пользователем.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь