Skip to content

Commit abfb6ad

Browse files
committed
fix(popup): 修复碰撞检测逻辑
1 parent 718f8f5 commit abfb6ad

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

src/popup/popup.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export default mixins(classPrefixMixins, getAttachConfigMixins('popup')).extend(
5151
/** popperjs instance */
5252
popper: null as ReturnType<typeof createPopper>,
5353
/** timeout id */
54-
timeout: null,
54+
timeout: null as ReturnType<typeof setTimeout>,
5555
hasDocumentEvent: false,
5656
/** if a trusted action (opening or closing) is prevented, increase this flag */
5757
visibleState: 0,
@@ -348,8 +348,12 @@ export default mixins(classPrefixMixins, getAttachConfigMixins('popup')).extend(
348348
// 子元素存在打开的 popup 时,ui 可能重叠,而 dom 节点多是并列关系
349349
// 需要做碰撞检测去阻止父级 popup 关闭
350350
if (this.visibleState > 1) {
351-
const rect = (this.$refs.popper as HTMLElement).getBoundingClientRect();
352-
if (ev.x > rect.x && ev.x < rect.x + rect.width && ev.y > rect.y && ev.y < rect.y + rect.height) return;
351+
// 优先使用实际可见的 overlay 容器进行碰撞检测;
352+
// 在某些场景下(如菜单子菜单弹层),popper 容器可能为 0x0(overlay 采用绝对定位脱离文档流),
353+
// 这会导致用 popper 计算的矩形始终为 0x0,从而误判离开范围,导致父级过早关闭。
354+
const rectTarget = (this.$refs.overlay as HTMLElement) || (this.$refs.popper as HTMLElement);
355+
const rect = rectTarget?.getBoundingClientRect?.();
356+
if (rect && ev.x > rect.x && ev.x < rect.x + rect.width && ev.y > rect.y && ev.y < rect.y + rect.height) return;
353357
}
354358
this.mouseInRange = false;
355359
this.handleClose({});

0 commit comments

Comments
 (0)