fix(personalization): 修复拖选文字松开落在遮罩上误关抽屉的问题

- 个人空间抽屉与角色编辑弹窗的遮罩关闭由 click.self/mousedown.self
  改为「按下与松开都发生在遮罩上」的成对判定
- 修复在输入框内拖选文字、松开落在遮罩上时被误判为点击遮罩,
  导致抽屉/角色编辑器意外关闭、表单内容丢失
This commit is contained in:
JOJO 2026-08-11 11:21:30 +08:00
parent 1c339d2e6f
commit b51b2597a8
2 changed files with 42 additions and 12 deletions

View File

@ -4,11 +4,11 @@
class="personal-page-overlay"
v-if="visible"
@click="closeDropdown"
@mousedown.self="personalization.handleOverlayPressStart($event)"
@mouseup.self="personalization.handleOverlayPressEnd"
@mousedown="personalization.handleOverlayPressStart($event)"
@mouseup="personalization.handleOverlayPressEnd($event)"
@mouseleave.self="personalization.handleOverlayPressCancel"
@touchstart.self.prevent="personalization.handleOverlayPressStart($event)"
@touchend.self.prevent="personalization.handleOverlayPressEnd"
@touchend="personalization.handleOverlayPressEnd($event)"
@touchcancel.self="personalization.handleOverlayPressCancel"
>
<div class="personal-page-card settings-redesign-card" data-tutorial="personal-card">
@ -1861,7 +1861,8 @@
v-if="roleEditorOpen"
class="role-editor-drawer-overlay"
@click="closeDropdown"
@click.self="closeRoleEditor"
@mousedown="handleRoleEditorOverlayPressStart"
@mouseup="handleRoleEditorOverlayPressEnd"
>
<div class="role-editor-drawer-card settings-redesign-card" style="padding: 30px 42px 24px; border-radius: 32px;" @click.stop>
<div class="role-editor-header">
@ -2866,6 +2867,25 @@ const closeRoleEditor = () => {
closeDropdown();
};
//
// click target
// @click.self
const roleEditorOverlayPressActive = ref(false);
const handleRoleEditorOverlayPressStart = (event: MouseEvent) => {
roleEditorOverlayPressActive.value =
event.target === event.currentTarget && event.button === 0;
};
const handleRoleEditorOverlayPressEnd = (event: MouseEvent) => {
const shouldClose =
roleEditorOverlayPressActive.value && event.target === event.currentTarget;
roleEditorOverlayPressActive.value = false;
if (shouldClose) {
closeRoleEditor();
}
};
const saveRole = async () => {
roleSaving.value = true;
try {

View File

@ -347,19 +347,29 @@ export const usePersonalizationStore = defineStore('personalization', {
this.overlayPressActive = false;
},
handleOverlayPressStart(event: Event) {
if (event && (event as MouseEvent).type === 'mousedown') {
const mouse = event as MouseEvent;
if (mouse.button !== 0) {
return;
}
// 只有直接按在遮罩上才算有效按压;按在卡片内部(如输入框)时重置状态,
// 避免「按下遮罩→拖入卡片松开」遗留的卡死状态导致后续遮罩 mouseup 误关抽屉
if (event.target !== event.currentTarget) {
this.overlayPressActive = false;
return;
}
if (event.type === 'mousedown' && (event as MouseEvent).button !== 0) {
return;
}
this.overlayPressActive = true;
},
handleOverlayPressEnd() {
if (!this.overlayPressActive) {
handleOverlayPressEnd(event: Event) {
// 按下与松开都发生在遮罩上才关闭;输入框内拖选文字、松开落在遮罩上时
// target 虽为遮罩,但按压并未起始于遮罩,不会关闭
const shouldClose =
this.overlayPressActive && event.target === event.currentTarget;
this.overlayPressActive = false;
if (!shouldClose) {
return;
}
this.overlayPressActive = false;
if (event.cancelable) {
event.preventDefault();
}
this.closeDrawer();
},
handleOverlayPressCancel() {