From 39dcd89acf8ed15fc965bd6678b5e7af21587177 Mon Sep 17 00:00:00 2001 From: roymondchen Date: Thu, 7 Apr 2022 15:20:09 +0800 Subject: [PATCH] =?UTF-8?q?fix(stage):=20=E4=BC=98=E5=8C=96=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=E4=BD=93=E9=AA=8C=EF=BC=8C=E5=BD=93=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E8=8A=82=E7=82=B9=E5=8F=98=E5=8C=96=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E9=87=8D=E6=96=B0=E5=88=9B=E5=BB=BAmoveable=EF=BC=8C=E5=A6=82?= =?UTF-8?q?=E6=9E=9C=E6=B2=A1=E6=9C=89=E5=8F=98=E5=8C=96=E5=88=99update?= =?UTF-8?q?=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/stage/src/StageCore.ts | 6 ++- packages/stage/src/StageDragResize.ts | 60 +++++++++++++++------------ packages/stage/src/StageMask.ts | 5 ++- 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/packages/stage/src/StageCore.ts b/packages/stage/src/StageCore.ts index b0ea5ea7..7892263b 100644 --- a/packages/stage/src/StageCore.ts +++ b/packages/stage/src/StageCore.ts @@ -173,10 +173,12 @@ export default class StageCore extends EventEmitter { // 更新配置后,需要等组件渲染更新 setTimeout(() => { const el = this.renderer.contentWindow?.document.getElementById(`${config.id}`); - if (el) { + // 有可能dom已经重新渲染,不再是原来的dom了,所以这里判断id,而不是判断el === this.selectedDom + if (el && el.id === this.selectedDom?.id) { + this.selectedDom = el; // 更新了组件的布局,需要重新设置mask是否可以滚动 this.mask.setLayout(el); - this.dr.select(el); + this.dr.updateMoveable(el); } }, 0); }); diff --git a/packages/stage/src/StageDragResize.ts b/packages/stage/src/StageDragResize.ts index 19e3a584..367afbfb 100644 --- a/packages/stage/src/StageDragResize.ts +++ b/packages/stage/src/StageDragResize.ts @@ -41,7 +41,7 @@ export default class StageDragResize extends EventEmitter { public core: StageCore; public container: HTMLElement; public target?: HTMLElement; - public dragEl?: HTMLElement; + public dragEl: HTMLElement; public moveable?: Moveable; public horizontalGuidelines: number[] = []; public verticalGuidelines: number[] = []; @@ -58,6 +58,9 @@ export default class StageDragResize extends EventEmitter { this.core = config.core; this.container = config.container; + + this.dragEl = globalThis.document.createElement('div'); + this.container.append(this.dragEl); } /** @@ -67,25 +70,13 @@ export default class StageDragResize extends EventEmitter { * @param event 鼠标事件 */ public select(el: HTMLElement, event?: MouseEvent): void { + const oldTarget = this.target; this.target = el; - // 如果有滚动条会导致resize时获取到width,height不准确 - if (/(auto|scroll)/.test(this.target.style.overflow)) { - this.target.style.overflow = 'hidden'; - } - this.mode = getMode(el); - this.destroyGhostEl(); - - this.generateDragEl(el); - - const originDraggable = this.moveableOptions.draggable; - - this.moveableOptions = this.getOptions({ - target: this.dragEl, - }); + this.init(el); // 从不能拖动到能拖动的节点之间切换,要重新创建moveable,不然dragStart不生效 - if (!this.moveable || originDraggable !== this.moveableOptions.draggable) { + if (!this.moveable || this.target !== oldTarget) { this.moveableHelper = MoveableHelper.create({ useBeforeRender: true, useRender: false, @@ -94,7 +85,7 @@ export default class StageDragResize extends EventEmitter { this.initMoveable(); } else { - this.refresh(); + this.updateMoveable(); } if (event) { @@ -105,8 +96,13 @@ export default class StageDragResize extends EventEmitter { /** * 初始化选中框并渲染出来 */ - public refresh() { + public updateMoveable(el = this.target): void { if (!this.moveable) throw new Error('未初始化moveable'); + if (!el) throw new Error('为选中任何节点'); + + this.target = el; + + this.init(el); Object.entries(this.moveableOptions).forEach(([key, value]) => { (this.moveable as any)[key] = value; @@ -123,7 +119,7 @@ export default class StageDragResize extends EventEmitter { this.moveableOptions.verticalGuidelines = guidelines; } - this.refresh(); + this.updateMoveable(); } public clearGuides() { @@ -131,7 +127,7 @@ export default class StageDragResize extends EventEmitter { this.verticalGuidelines = []; this.moveableOptions.horizontalGuidelines = []; this.moveableOptions.verticalGuidelines = []; - this.refresh(); + this.updateMoveable(); } /** @@ -145,6 +141,22 @@ export default class StageDragResize extends EventEmitter { this.removeAllListeners(); } + private init(el: HTMLElement): void { + // 如果有滚动条会导致resize时获取到width,height不准确 + if (/(auto|scroll)/.test(el.style.overflow)) { + el.style.overflow = 'hidden'; + } + this.mode = getMode(el); + + this.destroyGhostEl(); + + this.updateDragEl(el); + + this.moveableOptions = this.getOptions({ + target: this.dragEl, + }); + } + private initMoveable() { this.moveable?.destroy(); @@ -332,15 +344,10 @@ export default class StageDragResize extends EventEmitter { this.ghostEl = undefined; } - private generateDragEl(el: HTMLElement) { + private updateDragEl(el: HTMLElement) { const { width, height } = el.getBoundingClientRect(); const offset = getOffset(el); - if (!this.dragEl) { - this.dragEl = globalThis.document.createElement('div'); - this.container.append(this.dragEl); - } - this.dragEl.style.cssText = ` position: absolute; left: ${offset.left}px; @@ -354,7 +361,6 @@ export default class StageDragResize extends EventEmitter { private destroyDragEl(): void { this.dragEl?.remove(); - this.dragEl = undefined; } private getOptions(options: MoveableOptions = {}): MoveableOptions { diff --git a/packages/stage/src/StageMask.ts b/packages/stage/src/StageMask.ts index 3ab4fb3c..8669ed85 100644 --- a/packages/stage/src/StageMask.ts +++ b/packages/stage/src/StageMask.ts @@ -25,7 +25,7 @@ import type { StageMaskConfig } from './types'; import { createDiv, getScrollParent, isFixedParent } from './util'; const wrapperClassName = 'editor-mask-wrapper'; -const throttleTime = 100; +const throttleTime = 300; const hideScrollbar = () => { const style = globalThis.document.createElement('style'); @@ -215,6 +215,8 @@ export default class StageMask extends Rule { * @param event 事件对象 */ private mouseDownHandler = (event: MouseEvent): void => { + this.emit('clearHighlight'); + event.stopImmediatePropagation(); event.stopPropagation(); @@ -226,7 +228,6 @@ export default class StageMask extends Rule { } this.content.removeEventListener('mousemove', this.highlightHandler); - this.emit('clearHighlight'); this.emit('beforeSelect', event);