fix(editor): 延迟 FloatingBox 拖拽遮罩到实际位移时显示,修复关闭按钮点击失效

This commit is contained in:
roymondchen 2026-07-02 20:50:03 +08:00
parent 3b9fb714e5
commit 9aa251ce57
2 changed files with 43 additions and 7 deletions

View File

@ -98,15 +98,20 @@ let moveable: VanillaMoveable | null = null;
// / iframe iframe iframe
let dragMask: HTMLDivElement | null = null;
let dragMaskVisible = false;
const showDragMask = () => {
if (dragMaskVisible) {
return;
}
if (!dragMask) {
dragMask = globalThis.document.createElement('div');
dragMask.className = 'm-editor-float-box-drag-mask';
}
globalThis.document.body.appendChild(dragMask);
dragMaskVisible = true;
// root @mousedown="nextZIndex" dragStart z-index
// root @mousedown="nextZIndex" z-index
// iframe nextTick z-index
const setMaskZIndex = () => {
if (dragMask) {
@ -119,6 +124,7 @@ const showDragMask = () => {
const hideDragMask = () => {
dragMask?.parentNode?.removeChild(dragMask);
dragMaskVisible = false;
};
const initMoveable = () => {
@ -138,8 +144,11 @@ const initMoveable = () => {
bounds: { left: 0, top: 0, right: 0, bottom: 0, position: 'css' },
});
moveable.on('dragStart', showDragMask);
moveable.on('resizeStart', showDragMask);
// /moveable dragStart/resizeStart mousedown
// mouseup click
// drag/resize
moveable.on('drag', showDragMask);
moveable.on('resize', showDragMask);
moveable.on('dragEnd', hideDragMask);
moveable.on('resizeEnd', hideDragMask);

View File

@ -9,10 +9,13 @@ import { mount } from '@vue/test-utils';
import FloatingBox from '@editor/components/FloatingBox.vue';
const moveableHandlers = new Map<string, (...args: any[]) => void>();
const moveableHandlers = new Map<string, ((...args: any[]) => void)[]>();
const destroyMock = vi.fn();
let lastInstance: any;
const emitMoveable = (event: string, ...args: any[]) =>
(moveableHandlers.get(event) || []).forEach((fn) => fn(...args));
vi.mock('moveable', () => {
class FakeMoveable {
public target: any;
@ -26,7 +29,9 @@ vi.mock('moveable', () => {
moveableHandlers.clear();
}
public on(event: string, fn: (...args: any[]) => void) {
moveableHandlers.set(event, fn);
const list = moveableHandlers.get(event) || [];
list.push(fn);
moveableHandlers.set(event, list);
return this;
}
public destroy() {
@ -144,7 +149,7 @@ describe('FloatingBox.vue', () => {
});
await new Promise((r) => setTimeout(r, 0));
const target = document.createElement('div');
moveableHandlers.get('resize')?.({
emitMoveable('resize', {
width: 200,
height: 300,
target,
@ -163,7 +168,7 @@ describe('FloatingBox.vue', () => {
});
await new Promise((r) => setTimeout(r, 0));
const target = document.createElement('div');
moveableHandlers.get('drag')?.({ target, transform: 'translate(10px,20px)' });
emitMoveable('drag', { target, transform: 'translate(10px,20px)' });
expect(target.style.transform.replace(/\s+/g, '')).toBe('translate(10px,20px)');
});
@ -237,4 +242,26 @@ describe('FloatingBox.vue', () => {
wrapper.unmount();
expect(destroyMock).toHaveBeenCalled();
});
test('dragStart 时不显示拖拽遮罩,仅在真正 drag 时显示dragEnd 时移除', async () => {
const wrapper = mount(FloatingBox as any, {
props: { visible: true },
attachTo: document.body,
});
await new Promise((r) => setTimeout(r, 0));
await wrapper.vm.$nextTick();
// mousedowndragStart不应立即盖遮罩否则会盖住关闭按钮导致点击失效
emitMoveable('dragStart');
expect(document.querySelector('.m-editor-float-box-drag-mask')).toBeNull();
// 真正发生位移时才显示遮罩
emitMoveable('drag', { target: document.body, transform: 'translate(0,0)' });
expect(document.querySelector('.m-editor-float-box-drag-mask')).not.toBeNull();
// 拖拽结束移除遮罩
emitMoveable('dragEnd');
expect(document.querySelector('.m-editor-float-box-drag-mask')).toBeNull();
wrapper.unmount();
});
});