草庐IT

javascript - 删除元素后的 MutationObserver 行为

coder 2025-03-06 原文

我有一个 MutationObserver 绑定(bind)到 #foo html 元素。

var target = document.querySelector("#foo");
var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        // ...
    });
});

当用户点击 #button 元素时,#foo 会被移除并在一秒钟后再次出现。

<div id="button">Click me to remove the Foo!</div>
<div id="foo">Hello, I'm Foo!</div>

正如我所注意到的,在删除并重新创建 #foo 后,观察器停止工作。

  • 这是正常行为吗?
  • 那么,我需要再次启动观察器吗?

第三个问题:

  • 第一个观察者是否被完全移除?或者,相反,它仍在运行,只是“什么都不做”? - 我问这个问题,因为我不希望多个观察者运行,如果只有一个观察者在做真正的工作的话。

最佳答案

and appears again after a second

行为将完全取决于您的意思。

如果你的意思是创建一个具有相同 idnew 元素,那么是的,这是预期的行为:当你调用 observer.observe 在元素上,您是在那个特定元素 上调用它,而不是在任何与其 ID 匹配的元素上调用它。如果您从 DOM 中删除该元素并将其替换为另一个看起来相同的不同元素,则观察者不会神奇地连接到该新的不同元素:

var target = document.querySelector("#foo");
var observer = new MutationObserver(function(mutations) {
    console.log("#foo was modified");
});
observer.observe(target, {subTree: true, childList: true});
var counter = 0;
tick();
setTimeout(function() {
    console.log("Replacing foo with a new one");
    target.parentNode.removeChild(target);
    target = document.createElement("div");
    target.id = "foo";
    target.innerHTML = "This is the new foo";
    document.body.insertBefore(target, document.body.firstChild);
}, 1000);
function tick() {
    target.appendChild(document.createTextNode("."));
    if (++counter < 20) {
        setTimeout(tick, 200);
    }
}
<div id="foo">This is the original foo</div>

如果您的意思是将相同的元素放回到 DOM 中,那么不,这不是预期的行为,也不是本例中发生的情况:

var target = document.querySelector("#foo");
var observer = new MutationObserver(function(mutations) {
    console.log("#foo was modified");
});
observer.observe(target, {subTree: true, childList: true});
var counter = 0;
tick();
setTimeout(function() {
    console.log("Removing foo for a moment");
    target.parentNode.removeChild(target);
    setTimeout(function() {
        console.log("Putting the same foo back in");
        document.body.insertBefore(target, document.body.firstChild);
    }, 100);
}, 1000);
function tick() {
    target.appendChild(document.createTextNode("."));
    if (++counter < 20) {
        setTimeout(tick, 200);
    }
}
<div id="foo">This is the original foo</div>

此处的关键信息是观察者正在观察您传递给 observe一个特定元素


这些问题仅在您删除旧元素并将其替换为全新元素时适用:

So, I need to launch the observer again?

如果您要删除原始元素并放置一个新元素,您应该告诉观察者停止观察:

observer.disconnect();

一旦有了新元素,就可以将观察者连接到它:

observer.observe(theNewElement, /*...options go here...*/);

Is the first observer is totally removed? Or, instead of that, it is still running, with just "doing nothing"?

理论上,因为the spec清楚地表明它是引用其观察者的元素,然后如果您释放对该元素的唯一引用,理论上观察者会断开连接,因为该元素及其观察者列表已被清理。但是,尚不清楚观察者的 disconnect 方法如何在观察者没有返回元素的引用的情况下实现,因此它们可能具有相互引用。如果您保留对观察者的引用,那将在内存中保留相互引用。可以肯定的是,我会故意断开它。

I'm asking about it, because I don't want the multiple observers run, if only one of them doing the real work.

观察者不“跑”,他们 react 。观察者将继续观察原始元素,直到/除非您断开连接。如果您没有对原始元素做任何事情,那么观察者除了占用内存之外什么也没有做。但同样,如果您要删除该元素,您应该断开观察者的连接。

关于javascript - 删除元素后的 MutationObserver 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35253565/

有关javascript - 删除元素后的 MutationObserver 行为的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  2. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  3. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  4. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  5. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  6. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  7. ruby-on-rails - 标准化文件名的字符串,删除重音和特殊字符 - 2

    我正在尝试找到一种方法来规范化字符串以将其作为文件名传递。到目前为止我有这个:my_string.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n,'').downcase.gsub(/[^a-z]/,'_')但第一个问题:-字符。我猜这个方法还有更多问题。我不控制名称,名称字符串可以有重音符、空格和特殊字符。我想删除所有这些,用相应的字母('é'=>'e')替换重音符号,并将其余的替换为'_'字符。名字是这样的:“Prélèvements-常规”“健康证”...我希望它们像一个没有空格/特殊字符的文件名:“prelevements_routin

  8. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  9. ruby - Ruby gsub 替换中的行为不一致? - 2

    两个gsub产生不同的结果。谁能解释一下为什么?代码也可在https://gist.github.com/franklsf95/6c0f8938f28706b5644d获得.ver=9999str="\tCFBundleDevelopmentRegion\n\ten\n\tCFBundleVersion\n\t0.1.190\n\tAppID\n\t000000000000000"putsstr.gsub/(CFBundleVersion\n\t.*\.).*()/,"#{$1}#{ver}#{$2}"puts'--------'putsstr.gsub/(CFBundleVersio

  10. ruby - Hanami link_to 助手只呈现最后一个元素 - 2

    我是HanamiWorld的新人。我已经写了这段代码:moduleWeb::Views::HomeclassIndexincludeWeb::ViewincludeHanami::Helpers::HtmlHelperdeftitlehtml.headerdoh1'Testsearchengine',id:'title'hrdiv(id:'test')dolink_to('Home',"/",class:'mnu_orizontal')link_to('About',"/",class:'mnu_orizontal')endendendendend我在模板上调用了title方法。htm

随机推荐