76 lines
2.4 KiB
TypeScript
76 lines
2.4 KiB
TypeScript
/**
|
||
* DOM 事件模拟工具
|
||
* 封装仿真鼠标事件,用于触发 React/Vue 等框架 UI 组件库的弹出层
|
||
*
|
||
* 【重要】项目中所有需要触发弹出层的点击操作,必须使用此模块导出的 simulateClick,
|
||
* 禁止直接使用 .click()(普通 click 事件无法触发绑定在 mousedown 上的组件逻辑)
|
||
*/
|
||
|
||
/** 仿真点击的配置选项 */
|
||
interface SimulateClickOptions {
|
||
/** 是否触发 focus 事件(默认 false) */
|
||
focus?: boolean
|
||
/** 是否触发 pointerdown/pointerup 事件(默认 true,部分组件库监听 pointer 事件) */
|
||
pointer?: boolean
|
||
/** 点击坐标 clientX(默认取元素中心) */
|
||
clientX?: number
|
||
/** 点击坐标 clientY(默认取元素中心) */
|
||
clientY?: number
|
||
}
|
||
|
||
/**
|
||
* 仿真鼠标点击:完整的 mousedown → mouseup → click 事件链
|
||
* 模拟真实用户点击行为,兼容 React / Vue / Shimo Design / Ant Design 等组件库
|
||
*
|
||
* @param el - 目标 DOM 元素
|
||
* @param options - 可选配置(focus、pointer 事件、坐标)
|
||
*
|
||
* 使用场景:
|
||
* - 触发下拉选择器弹出层
|
||
* - 触发日期选择器面板
|
||
* - 触发级联选择器展开
|
||
* - 任何需要模拟真实鼠标点击的场景
|
||
*/
|
||
export function simulateClick(el: HTMLElement, options?: SimulateClickOptions): void {
|
||
const { focus = false, pointer = true, clientX, clientY } = options || {}
|
||
|
||
// 计算点击坐标(默认取元素中心点)
|
||
const rect = el.getBoundingClientRect()
|
||
const x = clientX ?? (rect.left + rect.width / 2)
|
||
const y = clientY ?? (rect.top + rect.height / 2)
|
||
|
||
/** 构造 MouseEvent 的公共参数 */
|
||
const mouseEventInit: MouseEventInit = {
|
||
bubbles: true,
|
||
cancelable: true,
|
||
clientX: x,
|
||
clientY: y,
|
||
button: 0,
|
||
buttons: 1,
|
||
}
|
||
|
||
// 1. focus(可选)
|
||
if (focus) {
|
||
el.focus()
|
||
}
|
||
|
||
// 2. pointer 事件(可选,部分组件库如 Radix UI 监听 pointerdown)
|
||
if (pointer) {
|
||
el.dispatchEvent(new PointerEvent("pointerdown", { ...mouseEventInit, pointerId: 1, pointerType: "mouse" }))
|
||
}
|
||
|
||
// 3. mousedown
|
||
el.dispatchEvent(new MouseEvent("mousedown", mouseEventInit))
|
||
|
||
// 4. pointerup(可选)
|
||
if (pointer) {
|
||
el.dispatchEvent(new PointerEvent("pointerup", { ...mouseEventInit, pointerId: 1, pointerType: "mouse" }))
|
||
}
|
||
|
||
// 5. mouseup
|
||
el.dispatchEvent(new MouseEvent("mouseup", mouseEventInit))
|
||
|
||
// 6. click
|
||
el.dispatchEvent(new MouseEvent("click", mouseEventInit))
|
||
}
|