As you said, MutationObserver
only allows you to detect when the children of an element are manipulated. That means you'll need to listen to the parent and check what changes were made to see if the target element was removed.
function onRemove(element, callback) {
const parent = element.parentNode;
if (!parent) throw new Error("The node must already be attached");
const obs = new MutationObserver(mutations => {
for (const mutation of mutations) {
for (const el of mutation.removedNodes) {
if (el === element) {
obs.disconnect();
callback();
}
}
}
});
obs.observe(parent, {
childList: true,
});
}
then with your example instead of
element.onRemove(() => releaseKraken(element));
you can do
onRemove(element, () => releaseKraken(element));
This approach should be plenty fast if all you are doing is watching a single element. While it may seem like a decent amount of looping, it is pretty rare for removedNodes
to be more than one node, and unless something is removing tons of siblings all at once, mutations
is going to be quite small too.
You could also consider doing
callback(el);
which would allow you to do
onRemove(element, releaseKraken);
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…