如何无需物理点击模拟触发react-ink按钮的点击动画?
解决方案
代码失效核心原因
- 事件坐标参数错误:react-ink计算动画起始位置依赖
clientX、clientY属性,你代码中传入的是screenX/screenY,属性不匹配导致动画触发判定不通过 - 缺少完整事件序列:多数版本的react-ink需要完整的
mousedown+mouseup事件流才能触发完整动画,仅触发mousedown不会执行动画 - 部分高版本react-ink默认监听
pointerdown事件而非mousedown,和你触发的事件类型不匹配
可直接复用的两种实现方案
方案1:修正模拟事件逻辑
const el = wrapperRef.current.querySelectorAll(`[data-target="${value.id}"]`)[0] const elPosition = el.getBoundingClientRect(); // 取按钮中心作为动画触发点,和物理点击效果一致 const centerX = elPosition.left + elPosition.width / 2 const centerY = elPosition.top + elPosition.height / 2 // 触发按下事件 const downEvt = new MouseEvent("mousedown", { view: window, bubbles: true, cancelable: true, clientX: centerX, clientY: centerY }); el.dispatchEvent(downEvt); // 间隔100ms触发抬起事件,模拟真实点击的时序 setTimeout(() => { const upEvt = new MouseEvent("mouseup", { view: window, bubbles: true, cancelable: true, clientX: centerX, clientY: centerY }) el.dispatchEvent(upEvt) }, 100)
如果上述代码不生效,将mousedown/mouseup替换为pointerdown/pointerup即可。
方案2:直接调用react-ink实例方法(更稳定)
不需要模拟事件,直接通过ref调用react-ink暴露的内置触发方法,兼容性更好:
// 定义ink组件的ref const inkRef = useRef(null) // 快捷键触发时直接调用方法 const triggerInk = () => { const elPosition = wrapperRef.current.querySelectorAll(`[data-target="${value.id}"]`)[0].getBoundingClientRect() inkRef.current?.trigger({ clientX: elPosition.left + elPosition.width / 2, clientY: elPosition.top + elPosition.height / 2 }) } // 给Ink组件绑定ref <div data-target={props.values.id} role="button"> <Ink hasTouch={false} ref={inkRef} /> </div>
内容的提问来源于stack exchange,提问作者peon123
相关产品推荐
相关产品推荐

