Eva*_*ler 3 javascript reactjs
我有一个 div,如果光标悬停在其上,则应该显示“HOVERING”,否则显示“NOT HOVERING”。由于某种原因,如果我慢慢地将每个 div 悬停在页面上,它的行为就会符合预期;但是,如果我在屏幕上快速移动光标,某些 div 就会被切换。意思是,当我的光标移动到 div 上时,它们将显示“NOT HOVERING”,当我的光标不在 div 上时,它们将显示“HOVERING”。
Chrome 和 Safari 中都会出现此错误。
沙盒:
https://codesandbox.io/s/ged-butterfly-r2g6x?file=/src/Geo.js
将光标快速移动到方框上以查看问题。
我认为您的实现的主要问题在于异步事件回调在事件循环中排队和处理的方式。我找不到有关处理事件回调延迟的任何硬细节,但如果您愿意深入研究,这里和这里的文档可能会进一步阐明这个问题。
基本上这个问题有两个方面:
将鼠标移动事件侦听器添加到窗口对象,并检查鼠标移动事件目标是否包含在您的元素之一中。如果当前未悬停且元素包含事件目标,则设置isHoveredtrue,如果当前悬停且元素不包含事件目标,则设置isHoveredfalse。
这并不能完全替代附加到包含的 Enter/leave|over/out 事件侦听器,div因为我仍然能够重现边缘情况。我注意到当快速移动鼠标并离开窗口时,您的 UI 最容易受到此问题的影响。
结合 window 和 div 事件侦听器可以提供相当好的分辨率(尽管我仍然能够重现边缘情况,但这要困难得多)。似乎也有一点帮助的是没有为 div 定义匿名回调函数。
import React, { createRef } from "react";
export default class Geo extends React.Component {
state = {
isHovering: false
};
mouseMoveRef = createRef();
componentDidMount() {
window.addEventListener("mousemove", this.checkHover, true);
}
componentWillUnmount() {
window.removeEventListener("mousemove", this.checkHover, true);
}
setHover = () => this.setState({ isHovering: true });
setUnhover = () => this.setState({ isHovering: false });
checkHover = e => {
if (this.mouseMoveRef.current) {
const { isHovering } = this.state;
const mouseOver = this.mouseMoveRef.current.contains(e.target);
if (!isHovering && mouseOver) {
this.setHover();
}
if (isHovering && !mouseOver) {
this.setUnhover();
}
}
};
render() {
var textDisplay;
if (this.state.isHovering) {
textDisplay = <span>HOVERING</span>;
} else {
textDisplay = <h1>NOT HOVERING</h1>;
}
return (
<div
ref={this.mouseMoveRef}
onMouseEnter={this.setHover}
onMouseLeave={this.setUnhover}
style={{ width: 300, height: 100, background: "green" }}
>
{textDisplay}
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9970 次 |
| 最近记录: |