弹窗点击位置定位技术实现解析
背景与效果
传统弹窗通常居中显示,但在以下场景存在体验问题:
- 操作链路过长时,用户视线需要频繁跳转
- 大屏场景下鼠标移动距离过远
- 移动端缺乏空间关联性
动态定位效果:
- 弹窗从点击位置附近弹出
- 自动避让视口边界
- 保持20px安全边距
- 视觉动效跟随操作焦点
整体方案
实现分为四个关键阶段:
- 坐标捕获:全局事件捕获
- 定位计算:初始位置 + 边界检测
- 样式注入:动态修改定位样式
- 状态清理:弹窗关闭时重置坐标
实现步骤详解
1. 事件捕获阶段
typescript
// 全局坐标存储器
let lastClickPosition = { x: -1000, y: -1000 };
// 捕获阶段监听点击事件
document.addEventListener('click', (e: MouseEvent) => {
lastClickPosition = {
x: e.clientX,
y: e.clientY
};
}, true);技术要点:
- 使用事件捕获阶段确保先于业务代码执行
- clientX/clientY获取视口绝对坐标
- 初始值设为屏幕外坐标作为异常保护
2. 弹窗初始化
tsx
function showConfirm() {
const basePos = lastClickPosition;
const modal = new Modal({
style: {
position: 'fixed',
left: `${basePos.x}px`,
top: `${basePos.y}px`,
transform: 'translate(-50%, -50%)'
}
});
// 边界检测
setTimeout(() => {
const rect = modal.element.getBoundingClientRect();
const viewport = {
width: window.innerWidth,
height: window.innerHeight
};
if (rect.right > viewport.width - 20) {
modal.element.style.left = `${viewport.width - rect.width - 20}px`;
}
if (rect.bottom > viewport.height - 20) {
modal.element.style.top = `${viewport.height - rect.height - 20}px`;
}
}, 0);
}3. 坐标清理
typescript
// 弹窗关闭时重置坐标
function closeModal() {
lastClickPosition = { x: -1000, y: -1000 };
}