Search code examples
javascripthtmlweb-componentcustom-element

Custom Elements: monkeypatch disconnected callback


I'm writing a web component enhancer function and I need to run something when the element is removed from the DOM - but I know this after the fact. I've used MutationObserver - but my component is used a lot around the page and multiple mutation observers are causing a performance issue.

Here's an attempt to do this without 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'

This doesn't work.

Is there a way to 'monkeypatch' disconnectedCallback?


Solution

  • I'd break it into two solutions, each closer to the specific use-case:

    • I (still, yep we talked about it) think, that if it is your own code that is creating the hiddenElement within that component - better to do the whole management within the component and not enrich/extend it from the outside (yes, even if you have this pattern repeated for a several components in the whole system)
    • If one absolutely wants to go enhancing the component from outside (say one not owns the class, or came to a multiple inheritance issue) - better to go with a standard event driven approach - disconnectedCallback should dispatch a disconnect event and the listener should be attached to it - otherwise this solution is just not scaleable / open for extensions (think of the case when another teammate need to add some more logic on disconnect, logic that is decoupled from the one found in the first listener)