Solution 1 :

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)

Solution 2 :

I’ve managed to come up with a “hack” that is working and is less costly than mutation observers.

The idea is to create a component inside the enhancer function, append it to the web component and run the cleanup function from inside the mock component.

Here’s an example:

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', () => {
        hostingForm.removeEventListener('reset', resetFormHandler);

This way, you can run any cleanup you want when your custom element is removed without creating multiple MutationObservers.

Problem :

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() {

window.customElements.define('test-component', TestComponent);

function enrichComponent(component) {
  const originalDisconnectedCallback = component.disconnectedCallback;
  component.disconnectedCallback = function() {

const component = document.createElement('test-component');
component.remove(); // logs 'CB' but no 'CB1'

This doesn’t work.

Is there a way to ‘monkeypatch’ disconnectedCallback?


Comment posted by GullerYA

Most likely you can’t override

Comment posted by GullerYA

Pay attention, that while added a whole new component (HTML element) to the DOM just for the side-effect of getting notified upon disconnection, which IMHO is an absolutely overkill and counter-intuitive solution, one need to take care that this element is not visible, nor interferes with possible CSS selectors based on elements positions etc.

Comment posted by

Thanks. As I mentioned – this is a hack until the proposal for a native disconnected event is done –