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" class="personal-page-overlay"
v-if="visible" v-if="visible"
@click="closeDropdown" @click="closeDropdown"
@mousedown.self="personalization.handleOverlayPressStart($event)" @mousedown="personalization.handleOverlayPressStart($event)"
@mouseup.self="personalization.handleOverlayPressEnd" @mouseup="personalization.handleOverlayPressEnd($event)"
@mouseleave.self="personalization.handleOverlayPressCancel" @mouseleave.self="personalization.handleOverlayPressCancel"
@touchstart.self.prevent="personalization.handleOverlayPressStart($event)" @touchstart.self.prevent="personalization.handleOverlayPressStart($event)"
@touchend.self.prevent="personalization.handleOverlayPressEnd" @touchend="personalization.handleOverlayPressEnd($event)"
@touchcancel.self="personalization.handleOverlayPressCancel" @touchcancel.self="personalization.handleOverlayPressCancel"
> >
<div class="personal-page-card settings-redesign-card" data-tutorial="personal-card"> <div class="personal-page-card settings-redesign-card" data-tutorial="personal-card">
@ -1861,7 +1861,8 @@
v-if="roleEditorOpen" v-if="roleEditorOpen"
class="role-editor-drawer-overlay" class="role-editor-drawer-overlay"
@click="closeDropdown" @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-drawer-card settings-redesign-card" style="padding: 30px 42px 24px; border-radius: 32px;" @click.stop>
<div class="role-editor-header"> <div class="role-editor-header">
@ -2866,6 +2867,25 @@ const closeRoleEditor = () => {
closeDropdown(); 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 () => { const saveRole = async () => {
roleSaving.value = true; roleSaving.value = true;
try { try {

View File

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