bigskysoftware / htmx

</> htmx - high power tools for HTML
https://htmx.org
Other
37.65k stars 1.27k forks source link

Remove-me extension should check if DOM node is still connected #2497

Open verheyenkoen opened 5 months ago

verheyenkoen commented 5 months ago

When the remove-me timeout fires, it will remove the node with the remove-me attribute from the DOM, like this: https://github.com/bigskysoftware/htmx/blob/adfd2c8bc8c710ee6935af7644de04e3081d099e/src/ext/remove-me.js#L6

However, in some cases, this node may already have been removed before the timeout fires and this code errors with:

Uncaught TypeError: Cannot read properties of null (reading 'removeChild')

A use case where this could happen is a flash toast message that also includes a dismiss button/icon (or gesture) and also removes the same node (or a parent) from the DOM.

I suggest to fix this using the Node.prototype.isConnected property within the setTimeout callback. Since IE11 compatibility is required, that would also require the isConnected-polyfill to be added.

verheyenkoen commented 5 months ago

As an alternative, the timeoutID from setTimeout could be stored in the nodes' dataset, so we have a way to cancel the timeout before it fires using clearTimeout, eg:

if (timing) {
    elt.dataset.removeMeTimeout = setTimeout(function () {
        elt.parentElement.removeChild(elt);
    }, htmx.parseInterval(timing));
}