检测给定元素已从DOM中删除而不牺牲性能 [英] Detect that given element has been removed from the DOM without sacrificing performance

查看:148
本文介绍了检测给定元素已从DOM中删除而不牺牲性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这些:

const element = this.getElementById("victim")

function releaseKraken(targetElement) {}

我希望在<$ c $时调用该函数c> element 从DOM中删除。

I want the function to be called when element is removed from DOM.

我可以想象这样的东西:

I can imagine something like this:

element.onRemove(() => releaseKraken(element))

我知道我需要 MutationObserver ,但是我发现的所有文档都集中在观察给定元素的孩子,而我需要观察元素本身。

I understand that I need MutationObserver, but all the documentation I found focuses on watching given element's children, whereas I need to watch the element itself.

UPD:问题如何检测从dom元素添加/删除的元素?
专注于观察给定父母的孩子。我不想看孩子或父母。当给定元素从DOM中删除时,我想收到通知。不是孩子。而且我不想在给定元素的父对象上设置观察者(除非这是唯一的选择),因为这会对性能产生影响。

UPD: the question How to detect element being added/removed from dom element? focuses on watching children of a given parent. I don't want to watch children or parent. I want to be notified when given element is removed from the DOM. Not it's children. And I don't want to set up a watcher on given element's parent (unless that's the only option) because it'll be a performance impact.

UPD2:如果我在文档上设置 MutationObserver ,这将导致每个会话触发回调数千甚至数百万次,并且每次回调都必须过滤掉一个庞大的已删除元素列表,以查看其中是否包含有问题的元素。

UPD2: if I set up a MutationObserver on document, this will result in the callback being triggered thousands or even millions of times per session, and each time the callback will have to filter a huge list of removed elements to see if it contains the one in question. That's just crazy.

我需要上面显示的简单内容。我希望回调函数被触发一次:删除给定元素时。

I need something simple like I showed above. I want the callback to be triggered exactly once: when the given element is removed.

推荐答案

如您所说, MutationObserver 仅允许您检测何时操纵元素的子代。这意味着您需要聆听父级并检查所做的更改以查看是否删除了目标元素。

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,
  });
}

然后以您的示例代替

element.onRemove(() => releaseKraken(element));

您可以做

onRemove(element, () => releaseKraken(element));

如果您只看单个元素,则此方法应该足够快。尽管看起来循环不错,但 removedNodes 可能不止一个节点,而且除非有一次将所有同胞全部删除,否则变异也将非常小。

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.

您也可以考虑这样做

callback(el);

这将允许您这样做

onRemove(element, releaseKraken);

这篇关于检测给定元素已从DOM中删除而不牺牲性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆