【发布时间】:2019-11-11 08:35:46
【问题描述】:
我正在尝试在 React 中实现拖放并使用 SVG 元素。问题是如果用户移动鼠标过快,mouseMove 不会被触发。它基本上经常失去拖动。为了解决这个问题,我认为我需要处理父级中的mouseMove,但不确定如何使用 React 来执行此操作。我尝试了几种不同的方法都无济于事。
我使用 ref 在父级上尝试了addEventListener('mousemove', ...),但问题是clientX 与当前组件的坐标系不同。此外,事件处理程序无权访问组件的任何状态(带有箭头函数的事件)。它维护对任何状态的过时引用。
我尝试在父级的context 中设置clientX 和clientY,然后将其从DragMe 组件中拉入,但由于某种奇怪的原因,第一次总是undefined我给它一个默认值。
这是我正在使用的代码:
const DragMe = ({ x = 50, y = 50, r = 10 }) => {
const [dragging, setDragging] = useState(false)
const [coord, setCoord] = useState({ x, y })
const [offset, setOffset] = useState({ x: 0, y: 0 })
const [origin, setOrigin] = useState({ x: 0, y: 0 })
const xPos = coord.x + offset.x
const yPos = coord.y + offset.y
const transform = `translate(${xPos}, ${yPos})`
const fill = dragging ? 'red' : 'green'
const stroke = 'black'
const handleMouseDown = e => {
setDragging(true)
setOrigin({ x: e.clientX, y: e.clientY })
}
const handleMouseMove = e => {
if (!dragging) { return }
setOffset({
x: e.clientX - origin.x,
y: e.clientY - origin.y,
})
}
const handleMouseUp = e => {
setDragging(false)
setCoord({ x: xPos, y: yPos })
setOrigin({ x: 0, y: 0 })
setOffset({ x: 0, y: 0 })
}
return (
<svg style={{ userSelect: 'none' }}
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseUp}
>
<circle transform={transform} cx="0" cy="0" r={r} fill={fill} stroke={stroke} />
</svg>
)
}
【问题讨论】:
-
尝试添加 e.preventDefault();在每个事件方法中
-
也尝试添加
e.stopPropagation() -
我最初尝试过,但问题不是某处的其他事件。问题是
mousemove仅在鼠标仍在对象上方时才会发出。当鼠标移动过快时,光标将在其位置更新之前离开对象。
标签: reactjs svg draggable react-hooks mousemove