我在组件挂载时通过在 useEffect 钩子中动态附加一个 div 元素来创建自定义光标,并使用事件侦听器将其设置为跟随鼠标。但是,两个 div 被渲染 — 一个正确地跟随鼠标,而另一个停留在视口的左上角。
import { useRef, useEffect, useState } from "react"
function Pcanvas({width, height, pixelSize}){
const [canvasColor, setCanvasColor] = useState("#dcdcdc")
const [pencilSize, setPencilSize] = useState(pixelSize)
const canvasRef = useRef(null)
var mousePressed = false
function mouseCursor(){
const cursor = document.createElement("div")
cursor.className = 'cursor'
cursor.style.backgroundColor = 'black'
cursor.style.width = pencilSize + 'px'
cursor.style.height = pencilSize + 'px'
cursor.style.position = 'absolute';
cursor.style.display = 'block';
cursor.style.zIndex = 999;
cursor.style.pointerEvents = 'none';
document.body.appendChild(cursor)
console.log(cursor.getBoundingClientRect().y)
}
function handleMouseMov(event){
const cursor = document.getElementsByClassName('cursor')[0]
console.log(cursor.getBoundingClientRect().y)
if(cursor){
cursor.style.top = event.clientY-(pencilSize/2) + 'px'
cursor.style.left = event.clientX-(pencilSize/2) + 'px'
}
}
function handleMouseLeave(event){
const cursor = document.getElementsByClassName('cursor')[0]
if(cursor){
cursor.style.display = 'none'
}
}
function handleMouseEnter(event){
const cursor = document.getElementsByClassName('cursor')[0]
if(cursor){
cursor.style.display = 'block'
}
}
useEffect(() => {
const canvas = canvasRef.current
mouseCursor()
document.body.addEventListener('mouseenter', handleMouseEnter)
document.body.addEventListener('mousemove', handleMouseMov)
document.body.addEventListener('mouseleave', handleMouseLeave)
return(() => {
document.body.removeEventListener('mouseenter', handleMouseEnter)
document.body.removeEventListener('mousemove', handleMouseMov)
document.body.removeEventListener('mouseleave', handleMouseLeave)
})
}, [pencilSize])
return(
<></>
)
}
export default Pcanvas
您应该避免
createElement
,尤其getElementsByClassName
是在使用 React 时。让组件自行渲染
div
,然后在需要时使用useRef
来更改任何样式。