mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2026-07-03 14:58:47 +08:00
fix(editor): 延迟 FloatingBox 拖拽遮罩到实际位移时显示,修复关闭按钮点击失效
This commit is contained in:
parent
3b9fb714e5
commit
9aa251ce57
@ -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);
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
// mousedown(dragStart)不应立即盖遮罩,否则会盖住关闭按钮导致点击失效
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user