diff --git a/src/columnmanager.js b/src/columnmanager.js index 4b2f749..fcfbaac 100644 --- a/src/columnmanager.js +++ b/src/columnmanager.js @@ -78,9 +78,13 @@ export default class ColumnManager { } }); - $.on(document.body, 'click', (e) => { + const deactivateDropdownOnBodyClick = (e) => { if (e.target.matches(toggleClass)) return; deactivateDropdown(); + }; + $.on(document.body, 'click', deactivateDropdownOnBodyClick); + this.instance.on('onDestroy', () => { + $.off(document.body, 'click', deactivateDropdownOnBodyClick); }); const dropdownItems = this.options.headerDropdown; @@ -126,7 +130,7 @@ export default class ColumnManager { startX = e.pageX; }); - $.on(document.body, 'mouseup', (e) => { + const onMouseup = (e) => { document.body.classList.remove('dt-resize'); if (!$resizingCell) return; isDragging = false; @@ -137,9 +141,13 @@ export default class ColumnManager { this.setColumnWidth(colIndex); this.style.setBodyStyle(); $resizingCell = null; + }; + $.on(document.body, 'mouseup', onMouseup); + this.instance.on('onDestroy', () => { + $.off(document.body, 'mouseup', onMouseup); }); - $.on(document.body, 'mousemove', (e) => { + const onMouseMove = (e) => { if (!isDragging) return; const finalWidth = startWidth + (e.pageX - startX); const { @@ -154,6 +162,10 @@ export default class ColumnManager { width: finalWidth }); this.setColumnHeaderWidth(colIndex); + }; + $.on(document.body, 'mousemove', onMouseMove); + this.instance.on('onDestroy', () => { + $.off(document.body, 'mousemove', onMouseMove); }); } diff --git a/src/datatable.js b/src/datatable.js index 8761c8a..8abebee 100644 --- a/src/datatable.js +++ b/src/datatable.js @@ -100,6 +100,7 @@ class DataTable { destroy() { this.wrapper.innerHTML = ''; this.style.destroy(); + this.fireEvent('onDestroy'); } appendRows(rows) { @@ -193,7 +194,22 @@ class DataTable { } fireEvent(eventName, ...args) { - this.events[eventName].apply(this, args); + // fire internalEventHandlers if any + // and then user events + const handlers = [ + ...(this._internalEventHandlers[eventName] || []), + this.events[eventName] + ].filter(Boolean); + + for (let handler of handlers) { + handler.apply(this, args); + } + } + + on(event, handler) { + this._internalEventHandlers = this._internalEventHandlers || {}; + this._internalEventHandlers[event] = this._internalEventHandlers[event] || []; + this._internalEventHandlers[event].push(handler); } log() { diff --git a/src/defaults.js b/src/defaults.js index f4c4e5c..6742c98 100644 --- a/src/defaults.js +++ b/src/defaults.js @@ -32,7 +32,8 @@ export default { onRemoveColumn(column) {}, onSwitchColumn(column1, column2) {}, onSortColumn(column) {}, - onCheckRow(row) {} + onCheckRow(row) {}, + onDestroy() {} }, sortIndicator: { asc: '↑', diff --git a/src/style.js b/src/style.js index f285b3b..f06bc24 100644 --- a/src/style.js +++ b/src/style.js @@ -30,18 +30,24 @@ export default class Style { } bindResizeWindow() { + this.onWindowResize = this.onWindowResize.bind(this); + this.onWindowResize = throttle(this.onWindowResize, 300); + if (this.options.layout === 'fluid') { - $.on(window, 'resize', throttle(() => { - this.distributeRemainingWidth(); - this.refreshColumnWidth(); - this.compensateScrollbarWidth(); - this.setBodyStyle(); - }, 300)); + $.on(window, 'resize', this.onWindowResize); } } + onWindowResize() { + this.distributeRemainingWidth(); + this.refreshColumnWidth(); + this.compensateScrollbarWidth(); + this.setBodyStyle(); + } + destroy() { this.styleEl.remove(); + $.off(window, 'resize', this.onWindowResize); } setStyle(selector, styleObject) {