React中useState结合onMouseMove添加Y偏移后鼠标定位异常求助
问题分析与修复方案
核心问题拆解
- zIndex样式无效:你写的
zIndex: "999px"是错误写法——zIndex要求是整数(无单位),带px的字符串会导致该样式失效,标记div可能被其他元素遮挡,看起来像是“消失”。 - 偏移触发意外的鼠标离开事件:给
event.pageY加42后,标记div的top位置向下偏移,容易超出监听鼠标移动的image容器范围,触发onMouseLeave,导致is_over变为false,标记div透明度被设为0,同时mouse_move不再执行,页面停止更新,直到鼠标重新移回容器。 - 频繁state更新引发性能问题:每次鼠标移动都调用
set_mouse触发组件重渲染,加偏移后会加剧性能消耗,出现卡顿、页面停止刷新的情况。
修复步骤
1. 修正zIndex样式
把带单位的zIndex改成纯整数,确保标记div在最上层:
const info_style = { zIndex: 999, // 移除px单位,改为整数 position: 'absolute', height: '20px', width: '20px', background: 'yellow', opacity: is_over ? 1 : 0, left: mouse.x, top: mouse.y, }
2. 调整鼠标定位基准,避免触发意外离开事件
将鼠标坐标从基于文档的pageX/pageY改为基于image容器的offsetX/offsetY,同时给容器添加相对定位,让标记div始终相对于容器定位,不会超出范围:
- 给容器容器添加相对定位(如果
container_style里没有的话):
const container_style = { position: 'relative', // 新增这一行 // 其他原有样式 }
- 修改鼠标移动事件的坐标计算:
const mouse_move = (event) => { // 使用offsetX/offsetY获取相对于image容器的坐标 let buf = {x: event.offsetX, y: event.offsetY + 42}; set_mouse(buf); }
3. 性能优化(可选)
用useRef存储鼠标位置,直接操作DOM更新样式,减少React state更新带来的频繁重渲染:
import { useRef } from 'react'; function Test() { // 其他代码 const mouseRef = useRef({x:0, y:0}); const infoDivRef = useRef(null); const mouse_move = (event) => { mouseRef.current = {x: event.offsetX, y: event.offsetY + 42}; // 用requestAnimationFrame保证平滑更新 requestAnimationFrame(() => { if (infoDivRef.current) { infoDivRef.current.style.left = `${mouseRef.current.x}px`; infoDivRef.current.style.top = `${mouseRef.current.y}px`; } }); } const info_style = { zIndex: 999, position: 'absolute', height: '20px', width: '20px', background: 'yellow', opacity: is_over ? 1 : 0, // 移除left和top,改为通过ref直接操作 } // 其他代码 return( <div style={container_style}> <div style={image_style} onMouseEnter={mouse_enter} onMouseLeave={mouse_leave} onMouseMove={mouse_move}> <GatsbyImage image={getImage(img)} alt={img.base}/> </div> <div ref={infoDivRef} style={info_style} ></div> </div> ) }
内容的提问来源于stack exchange,提问作者Knupel
相关产品推荐
相关产品推荐

