问题描述
我正在编写一个Web组件增强器函数,当从DOM中删除该元素时,我需要运行一些东西-但我知道这一点。 我曾经使用过MutationObserver-但是我的组件在页面上使用了很多,并且多个变异观察器导致性能问题。
尝试在没有MutationObserver的情况下执行此操作:
class TestComponent extends HTMLElement {
disconnectedCallback() {
console.log('CB');
}
}
window.customElements.define('test-component',TestComponent);
function enrichComponent(component) {
const originaldisconnectedCallback = component.disconnectedCallback;
component.disconnectedCallback = function() {
originaldisconnectedCallback();
console.log('CB1');
}
}
const component = document.createElement('test-component');
enhancer(component);
document.body.appendChild(component);
component.remove(); // logs 'CB' but no 'CB1'
这不起作用。
有没有办法'monkeypatch'disconnectedCallback
?
解决方法
我将其分为两个解决方案,每个解决方案都更接近于特定的用例:
- 我(仍然,是我们谈论过的)认为,如果是您自己的代码在该组件内创建
hiddenElement
,则最好在该组件内进行整个管理而不是丰富/扩展它从外部(是的,即使您对整个系统中的多个组件重复了此模式) - 如果一个人绝对想从外部增强组件(例如,一个人不拥有该类,或者遇到了多重继承问题)-最好使用标准的事件驱动方法-
disconnectedCallback
应该派发一个{ {1}}事件和侦听器应该附加到该事件上-否则,该解决方案就不能扩展/扩展(例如,当另一个队友需要在断开连接时添加更多逻辑,与发现的逻辑分离的逻辑时)在第一个听众中)
我设法提出了一种“变种”,该变种正在起作用,并且比变异观察员的花费要低。
这个想法是在增强器函数内部创建一个组件,将其附加到Web组件,然后从模拟组件内部运行清除函数。
这是一个例子:
class FormAssociationDisconnectionComponent extends HTMLElement {
disconnectedCallback() {
this.dispatchEvent(new Event('disconnected'));
}
}
window.customElements.define('form-association-disconnection',FormAssociationDisconnectionComponent);
function enrichComponent(component) {
// ... setup a form and a hidden input we need to cleanup
const removeListenerElement = document.createElement('form-association-disconnection');
removeListenerElement.addEventListener('disconnected',() => {
hiddenInput.remove();
hostingForm.removeEventListener('reset',resetFormHandler);
});
inputElement.appendChild(removeListenerElement);
}
这样,您可以在删除自定义元素时运行所需的任何清理操作,而无需创建多个MutationObserver。