fix(destroy): Cleanup event listeners on destroy
Event listeners attached to elements inside the root datatable wrapper are automatically removed when the root element is removed from DOM. But, there are event listeners which are attached to window and body, those have to be manually removed. This commit introduces an internal event system, through which we destroy global event handlers.
This commit is contained in:
parent
f9714673b4
commit
bddb3c27ce
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -32,7 +32,8 @@ export default {
|
||||
onRemoveColumn(column) {},
|
||||
onSwitchColumn(column1, column2) {},
|
||||
onSortColumn(column) {},
|
||||
onCheckRow(row) {}
|
||||
onCheckRow(row) {},
|
||||
onDestroy() {}
|
||||
},
|
||||
sortIndicator: {
|
||||
asc: '↑',
|
||||
|
||||
18
src/style.js
18
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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user