为啥元素从 DOM 中移除后仍可访问?

     2023-05-09     165

关键词:

【中文标题】为啥元素从 DOM 中移除后仍可访问?【英文标题】:Why is an element accessible even after being removed from DOM?为什么元素从 DOM 中移除后仍可访问? 【发布时间】:2015-12-13 08:59:19 【问题描述】:

window.a = 
  div1: $('#div1'),
  img1: $('#img1')
;

$(a.img1).click(function() 
  a.div1.html('<img id="img2" src="https://www.gstatic.com/webp/gallery/2.sm.jpg" />');
  $('#img2').click(function() 
    $(a.img1).attr('src', 'https://www.gstatic.com/webp/gallery/3.sm.jpg');
  );
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="div1">
  <img id="img1" src="https://www.gstatic.com/webp/gallery/1.sm.jpg" />
</div>

当第 9 行执行时,即第二次单击图像时$(a.img1).attr('src', 'https://www.gstatic.com/webp/gallery/3.sm.jpg');,a.img1 不应该存在。那么,为什么该 URL 的 HTTP 请求被发送到服务器(网络选项卡中的通知)?我正在使用 Chrome 版本 45.0.2454.85 m。不要认为这是一个浏览器错误。也适用于 Firefox 39。

还做了一个提琴手http://jsfiddle.net/ismusidhu/vvmwntcd/。

【问题讨论】:

您已经从 DOM 树中删除了该节点,但它仍然存在,因为 window.img1 仍然指向它 - 所以它不能被垃圾回收。 “为什么元素从 DOM 中移除后仍然可以访问?”DOM 中移除的元素在哪里? @guest271314 a.div1.html() 应该删除它。不是吗? @IsmailS 是的,你是对的;从DOM 中删除,但仍然是window.a.img1 处的jQuery 对象 如果你从酒店房间偷了遥控器,当你按下按钮时它仍然会闪烁灯,即使它不会对任何其他电视做任何事情...... 【参考方案1】:

作为Marc B said,您已经从DOM 树中删除了该节点,但它仍然存在,因为window.img1 仍然指向它(间接地,通过指向一个反过来指向它的jQuery 对象)——所以它不能被垃圾回收。如果将window.img1 设置为不同的值(例如nullundefined),则可以对元素进行垃圾回收。

这样想:你从指向它的图像的父元素(以及各种兄弟元素,但暂时忽略它)开始:

+------------------+ +------------------+ | (一些 DOM 元素)|---------->| | +---------------------+ | | |图像元素| +--------+ | | | img1 |------------>| | +------+ +------------------+

然后,当您在其祖先上调用 html 时,DOM 会删除对该元素的所有引用,并且您会得到:

+-------------------+ | | | | |图像元素| +--------+ | | | img1 |------------>| | +------+ +------------------+

释放最后一个引用,元素可以被回收/释放。

【讨论】:

这是一个真实的答案,那你为什么把它作为社区维基? @IsmailS:CW 是真正的答案。当我看到有人评论了(一个​​不完整的版本)如果答案很短,我会回答什么时,我经常勾选 CW 框。我不关心代表,这似乎有助于避免抱怨从 cmets 那里“偷走”他们的“答案”。 (我不认为 Marc B 会那样抱怨,但我是从别人那里得到的,所以......) 那是您的伟大,先生!无论如何,如果有人抱怨窃取答案,那一定是他们的错。你已经详细说明了。他们没有。 ;)【参考方案2】:

window.a = 
  div1: $('#div1'),
  img1: function() 
    return $("> img[id]", this.div1)
  
;

function toggle(e) 
  a.div1.html(/1/.test(e.target.src) 
             ? '<img id="img2" src="https://www.gstatic.com/webp/gallery/2.sm.jpg" />' 
             : $('<img id="img1" src="https://www.gstatic.com/webp/gallery/1.sm.jpg" />')
               .click(toggle)
  );
  
  $("#img2").on("click", function(e) 
    a.img1().attr(
        'src': 'https://www.gstatic.com/webp/gallery/3.sm.jpg',
        "id": "img3"
      )
      .click(toggle)
  );


a.img1().click(toggle);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="div1">
  <img id="img1" src="https://www.gstatic.com/webp/gallery/1.sm.jpg" />
</div>

jsfiddle http://jsfiddle.net/vvmwntcd/6/

【讨论】:

浏览器仍然向https://www.gstatic.com/webp/gallery/3.sm.jpg发出请求。在网络选项卡上检查。控制台确实显示undefined @IsmailS:控制台显示undefined 的唯一原因是代码输出a.img 而不是a.img1。这样做is 检查 before 元素被删除并不会让它在以后神奇地消失。如果你使用corrected version,你会看到a.img1仍然是一个jQuery对象(当然),a.img1[0]仍然有一个HTMLInputElement对象的引用(当然)。 @IsmailS:你的问题的答案是 Marc B 早先所说的:它仍然存在,因为仍然有对它的引用。在显示图像之前使用断开连接的img 获取图像是一种常用技术。为避免这种情况发生,请清除 img1

modalViewController 从 superview 中移除后 UIView 消失

】modalViewController从superview中移除后UIView消失【英文标题】:UIViewdisappearsaftermodalViewControllerisremovedfromsuperview【发布时间】:2009-08-0412:51:22【问题描述】:在我的应用程序中,我有一个tabBarController和一个navigationController。我的视图... 查看详情

SKSpriteNode 从场景中移除后如何停止音频(Swift)?

】SKSpriteNode从场景中移除后如何停止音频(Swift)?【英文标题】:HowtostopanaudioofSKSpriteNodeafteritsremovedfromthescene(Swift)?【发布时间】:2016-03-2819:45:45【问题描述】:这是我的代码:overridefuncdidMoveToView(view:SKView)/*Setupyourscenehere*/letba... 查看详情

从 DOM 中移除的元素中取消绑定事件

】从DOM中移除的元素中取消绑定事件【英文标题】:UnbindeventsfromelementsthatareremovedfromtheDOM【发布时间】:2014-05-2215:32:50【问题描述】:我正在与一位开发人员讨论我们在iOS设备上使用网络应用时遇到的问题。它大量使用事件和jQu... 查看详情

移除元素

 方法 说明remove()从DOM中移除匹配的元素及其所有后代和文本节点。detach()从DOM中移除匹配的元素及其所有后代和文本节点。还会在内存中保留副本。通常使用remove()方法。empty()从DOM中移除匹配元素子节点及后代。unwrap()移... 查看详情

CALayer 帧值即使在从超级层中移除后也会导致动画

】CALayer帧值即使在从超级层中移除后也会导致动画【英文标题】:CALayerframevaluecausinganimationevenafterremovalfromsuperlayer【发布时间】:2013-02-2416:31:26【问题描述】:进入CALayer世界:我正在创建一个无论设备方向如何都需要保持在视... 查看详情

从 DOM 数组中移除 DOM 对象

】从DOM数组中移除DOM对象【英文标题】:removingaDOMobjectfromanarrayofDOM【发布时间】:2012-08-1117:02:13【问题描述】:如果我使用这个$("div:jqmData(role=\'page\')"),它将返回我的DOM对象中的页面数组。但是jquerymobile创建了一个没有... 查看详情

jquery4种移除清空元素的方法

参考技术A将匹配的元素集合的子节点元素都移除,包括子节点的嵌套元素清空当前元素的内容将匹配的元素集合从dom中移除例如$(".cls").remove()或者$('div').remove(".cls")注意:调用方法的元素本身也会移除将匹... 查看详情

html元素移除回调

您可以使用JavaScript中的removeChild()函数来移除HTML元素。该函数接受一个参数,即要移除的元素。该函数会从DOM中移除指定的元素,并返回该元素。此外,您还可以使用removeEventListener()函数来移除HTML元素的回调函数。该函数接受... 查看详情

当不透明度为 0% 时从元素中移除点击

】当不透明度为0%时从元素中移除点击【英文标题】:Removeclickingfromelementwhenopacityisat0%【发布时间】:2012-09-0701:04:43【问题描述】:我的页面上有一些内容需要淡出到0%的不透明度,而不是淡出并将元素从页面中完全移除,因此... 查看详情

18怎样从一个数组中移除反复的元素

两种方法(1)使用LINQ(2)使用ListstaticvoidRemoveDups(string[]myStringArray){//LINQstring[]str=myStringArray.Distinct().ToArray();//ArraytoListtoArrayList<String>myStringList=newList<string>();foreac 查看详情

从二维平衡 KD-Tree 中移除元素

】从二维平衡KD-Tree中移除元素【英文标题】:RemovingelementfrombalancedKD-Treeoftwodimensions【发布时间】:2013-11-2507:41:38【问题描述】:我想从平衡的KD-Tree中删除一个元素,并且Tree保持平衡而不重建整个树。这是否可以在不重建整棵... 查看详情

Play Framework 2.4.1:如何从 JsArray 中移除元素

】PlayFramework2.4.1:如何从JsArray中移除元素【英文标题】:PlayFramework2.4.1:HowtoremoveanelementfromaJsArray【发布时间】:2015-06-2918:54:16【问题描述】:鉴于以下JSON...scala>valjs=Json.parse(""""key1":"value1","key2":"value2","list":["item1":"value1 查看详情

在 KineticJS 中移除舞台

】在KineticJS中移除舞台【英文标题】:RemovingtheStageinKineticJS【发布时间】:2012-12-1300:53:49【问题描述】:如何删除KineticJSStage?问题:stage.removeChildren()成功删除了其子代,例如layers。但是stage.remove()并没有移除stage,如下jsfiddle所... 查看详情

guavacache为啥删除元素时移动元素

参考技术A在guava中数据的移除分为被动移除和主动移除两种被动移除数据的方式,guava默认提供了三种方式:基于大小的移除  看字面意思就知道就是按照缓存的大小来移除,如果即将到达指定的大小,那就会把不常用的... 查看详情

在 O(n) 时间内从容器中移除 <number> 个元素

】在O(n)时间内从容器中移除<number>个元素【英文标题】:Remove<number>ofelementsfromacontainerinO(n)time【发布时间】:2013-02-2000:28:43【问题描述】:假设您想实现一个模板化函数,该函数接受两个迭代器到一个容器和一个整数,... 查看详情

leetcode2091.从数组中移除最大值和最小值(代码片段)

...c;数组由若干互不相同的整数组成。nums中有一个值最小的元素和一个值最大的元素。分别称为最小值和最大值。你的目标是从数组中移除这两个元素。一次删除操作定义为从数组的前面移除一个元素或从数组的后面移 查看详情

从微调器中移除焦点

...个数组,我从中比较在编辑文本中键入的字母,过滤数组元素后,我将它们添加到微调器中并打开微调器。我面临的问题是,当微调器打开时,edittext失去焦点,我需要关闭微调器才能再次开始 查看详情

为啥 C++11 会从 std::vector 填充构造函数的原型中移除默认值?

】为啥C++11会从std::vector填充构造函数的原型中移除默认值?【英文标题】:WhydidC++11removethedefaultvaluefromtheprototypesofstd::vector\'sfillconstructor?为什么C++11会从std::vector填充构造函数的原型中移除默认值?【发布时间】:2018-02-0603:41:52... 查看详情