diff --git a/src/editor/core/contextmenu/ContextMenu.ts b/src/editor/core/contextmenu/ContextMenu.ts index c40283c..39c9939 100644 --- a/src/editor/core/contextmenu/ContextMenu.ts +++ b/src/editor/core/contextmenu/ContextMenu.ts @@ -49,13 +49,22 @@ export class ContextMenu { ] this.contextMenuContainerList = [] this.contextMenuRelationShip = new Map() + this._addEvent() + } + + private _addEvent() { // 接管菜单权限 - document.addEventListener('contextmenu', this._proxyContextMenuEvent.bind(this)) + document.addEventListener('contextmenu', this._proxyContextMenuEvent) // 副作用处理 - document.addEventListener('mousedown', this._handleEffect.bind(this)) + document.addEventListener('mousedown', this._handleEffect) + } + + public removeEvent() { + document.removeEventListener('contextmenu', this._proxyContextMenuEvent) + document.removeEventListener('mousedown', this._handleEffect) } - private _proxyContextMenuEvent(evt: MouseEvent) { + private _proxyContextMenuEvent = (evt: MouseEvent) => { this.context = this._getContext() const renderList: IRegisterContextMenu[] = [] let isRegisterContextMenu = false @@ -82,7 +91,7 @@ export class ContextMenu { evt.preventDefault() } - private _handleEffect(evt: MouseEvent) { + private _handleEffect = (evt: MouseEvent) => { if (this.contextMenuContainerList.length) { // 点击非右键菜单内 const contextMenuDom = findParent( diff --git a/src/editor/core/draw/Draw.ts b/src/editor/core/draw/Draw.ts index 238aca9..4d8b278 100644 --- a/src/editor/core/draw/Draw.ts +++ b/src/editor/core/draw/Draw.ts @@ -63,6 +63,7 @@ export class Draw { private listener: Listener private canvasEvent: CanvasEvent + private globalEvent: GlobalEvent private cursor: Cursor private range: RangeManager private margin: Margin @@ -91,6 +92,8 @@ export class Draw { private blockParticle: BlockParticle private control: Control private workerManager: WorkerManager + private scrollObserver: ScrollObserver + private selectionObserver: SelectionObserver private rowList: IRow[] private painterStyle: IElementStyle | null @@ -99,12 +102,12 @@ export class Draw { private intersectionPageNo: number constructor( - container: HTMLDivElement, + rootContainer: HTMLElement, options: DeepRequired, elementList: IElement[], listener: Listener ) { - this.container = container + this.container = this._wrapContainer(rootContainer) this.pageList = [] this.ctxList = [] this.pageNo = 0 @@ -145,14 +148,14 @@ export class Draw { this.blockParticle = new BlockParticle(this) this.control = new Control(this) - new ScrollObserver(this) - new SelectionObserver() + this.scrollObserver = new ScrollObserver(this) + this.selectionObserver = new SelectionObserver() this.canvasEvent = new CanvasEvent(this) this.cursor = new Cursor(this, this.canvasEvent) this.canvasEvent.register() - const globalEvent = new GlobalEvent(this, this.canvasEvent) - globalEvent.register() + this.globalEvent = new GlobalEvent(this, this.canvasEvent) + this.globalEvent.register() this.workerManager = new WorkerManager(this) @@ -513,6 +516,12 @@ export class Draw { } } + private _wrapContainer(rootContainer: HTMLElement): HTMLDivElement { + const container = document.createElement('div') + rootContainer.append(container) + return container + } + private _formatContainer() { // 容器宽度需跟随纸张宽度 this.container.style.position = 'relative' @@ -1171,4 +1180,11 @@ export class Draw { }) } + public destroy() { + this.container.remove() + this.globalEvent.removeEvent() + this.scrollObserver.removeEvent() + this.selectionObserver.removeEvent() + } + } \ No newline at end of file diff --git a/src/editor/core/event/GlobalEvent.ts b/src/editor/core/event/GlobalEvent.ts index eacda88..0f67c2f 100644 --- a/src/editor/core/event/GlobalEvent.ts +++ b/src/editor/core/event/GlobalEvent.ts @@ -38,21 +38,24 @@ export class GlobalEvent { public register() { this.cursor = this.draw.getCursor() - document.addEventListener('keyup', () => { - this.setRangeStyle() - }) - document.addEventListener('click', (evt) => { - this.recoverEffect(evt) - }) - document.addEventListener('mouseup', () => { - this.setDragState() - }) - document.addEventListener('wheel', (evt: WheelEvent) => { - this.setPageScale(evt) - }, { passive: false }) + this.addEvent() + } + + private addEvent() { + document.addEventListener('keyup', this.setRangeStyle) + document.addEventListener('click', this.recoverEffect) + document.addEventListener('mouseup', this.setDragState) + document.addEventListener('wheel', this.setPageScale, { passive: false }) + } + + public removeEvent() { + document.removeEventListener('keyup', this.setRangeStyle) + document.removeEventListener('click', this.recoverEffect) + document.removeEventListener('mouseup', this.setDragState) + document.removeEventListener('wheel', this.setPageScale) } - public recoverEffect(evt: MouseEvent) { + public recoverEffect = (evt: MouseEvent) => { if (!this.cursor) return const cursorDom = this.cursor.getCursorDom() const agentDom = this.cursor.getAgentDom() @@ -80,15 +83,15 @@ export class GlobalEvent { this.control.destroyControl() } - public setDragState() { + public setDragState = () => { this.canvasEvent.setIsAllowDrag(false) } - public setRangeStyle() { + public setRangeStyle = () => { this.range.setRangeStyle() } - public setPageScale(evt: WheelEvent) { + public setPageScale = (evt: WheelEvent) => { if (!evt.ctrlKey) return evt.preventDefault() const { scale } = this.options diff --git a/src/editor/core/observer/ScrollObserver.ts b/src/editor/core/observer/ScrollObserver.ts index e65e87f..a68fa15 100644 --- a/src/editor/core/observer/ScrollObserver.ts +++ b/src/editor/core/observer/ScrollObserver.ts @@ -21,10 +21,18 @@ export class ScrollObserver { this._observer() } }) - document.addEventListener('scroll', debounce(this._observer.bind(this), 150)) + this._addEvent() } - private _observer() { + private _addEvent() { + document.addEventListener('scroll', this._observer) + } + + public removeEvent() { + document.removeEventListener('scroll', this._observer) + } + + private _observer = debounce(() => { const rect = this.pageContainer.getBoundingClientRect() const top = Math.abs(rect.top) const bottom = top + window.innerHeight @@ -55,6 +63,6 @@ export class ScrollObserver { } this.draw.setIntersectionPageNo(intersectionPageNo) this.draw.setVisiblePageNoList(visiblePageNoList) - } + }, 150) } \ No newline at end of file diff --git a/src/editor/core/observer/SelectionObserver.ts b/src/editor/core/observer/SelectionObserver.ts index fa83239..5eee804 100644 --- a/src/editor/core/observer/SelectionObserver.ts +++ b/src/editor/core/observer/SelectionObserver.ts @@ -20,22 +20,31 @@ export class SelectionObserver { this.isMoving = false this.clientWidth = 0 this.clientHeight = 0 + this._addEvent() + } + + private _addEvent() { + document.addEventListener('mousedown', this._mousedown) + document.addEventListener('mousemove', this._mousemove) + document.addEventListener('mouseup', this._mouseup) + } - document.addEventListener('mousedown', this._mousedown.bind(this)) - document.addEventListener('mousemove', this._mousemove.bind(this)) - document.addEventListener('mouseup', this._mouseup.bind(this)) + public removeEvent() { + document.removeEventListener('mousedown', this._mousedown) + document.removeEventListener('mousemove', this._mousemove) + document.removeEventListener('mouseup', this._mouseup) } - private _mousedown() { + private _mousedown = () => { this.isMousedown = true } - private _mouseup() { + private _mouseup = () => { this.isMousedown = false this._stopMove() } - private _mousemove(evt: MouseEvent) { + private _mousemove = (evt: MouseEvent) => { if (!this.isMousedown) return const { x, y } = evt if (y < this.tippingPoints[0]) { diff --git a/src/editor/core/shortcut/Shortcut.ts b/src/editor/core/shortcut/Shortcut.ts index fab6704..f09c77c 100644 --- a/src/editor/core/shortcut/Shortcut.ts +++ b/src/editor/core/shortcut/Shortcut.ts @@ -18,12 +18,20 @@ export class Shortcut { ...richtextKeys ]) // 全局快捷键 - document.addEventListener('keydown', this._globalKeydown.bind(this)) + this._addEvent() // 编辑器快捷键 const agentDom = draw.getCursor().getAgentDom() agentDom.addEventListener('keydown', this._agentKeydown.bind(this)) } + private _addEvent() { + document.addEventListener('keydown', this._globalKeydown) + } + + public removeEvent() { + document.removeEventListener('keydown', this._globalKeydown) + } + private _addShortcutList(payload: IRegisterShortcut[]) { for (let s = 0; s < payload.length; s++) { const shortCut = payload[s] @@ -39,7 +47,7 @@ export class Shortcut { this._addShortcutList(payload) } - private _globalKeydown(evt: KeyboardEvent) { + private _globalKeydown = (evt: KeyboardEvent) => { if (!this.globalShortcutList.length) return this._execute(evt, this.globalShortcutList) } diff --git a/src/editor/index.ts b/src/editor/index.ts index cd84525..09de2f1 100644 --- a/src/editor/index.ts +++ b/src/editor/index.ts @@ -34,6 +34,7 @@ export default class Editor { public command: Command public listener: Listener public register: Register + public destroy: Function constructor(container: HTMLDivElement, elementList: IElement[], options: IEditorOption = {}) { const headerOptions: Required = { @@ -111,6 +112,12 @@ export default class Editor { contextMenu, shortcut }) + // 注册销毁方法 + this.destroy = () => { + draw.destroy() + shortcut.removeEvent() + contextMenu.removeEvent() + } } } diff --git a/src/style.css b/src/style.css index c7f0855..7d0e05e 100644 --- a/src/style.css +++ b/src/style.css @@ -605,7 +605,7 @@ ul { background-image: url('./assets/images/print.svg'); } -.editor { +.editor>div { margin: 80px auto; }