DOM:裁剪元素并使用parentNode

时间:2013-06-25 21:52:40

标签: javascript dom

考虑这个简单的页面:

<html>
<head>
<script>
    var upper;
    var lower;

    function crop() {
      //upper = document.getElementById('upper');
      lower = document.getElementById('lower');
      document.body.innerHTML = '';  
      document.body.appendChild(lower.cloneNode(true));
    }

    function up() {
      document.body.innerHTML = '';  
      document.body.appendChild(lower.parentNode);
    }
</script>
</head>
<body>
    <div id="upper">
      Upper Div
      <div id="lower">
        Lower Div
        <button onclick="crop()">Crop</button>
        <button onclick="up()">Up</button>
      </div>
    </div>
</body>
</html>

所以Crop按钮清除身体,克隆下部div并将其附加到身体上。 Up按钮的目的是使下div的父级可见(upper div)。在我的第一次尝试中,我尝试使用lower.parentNode,这不起作用,因为它是null。我认为这是因为变量lower现在指向一个DOM元素,它不是正文的一部分。 (我的理解是否正确?)但现在考虑注释行:

//upper = document.getElementById('upper');

除了获得对上部div的引用之外什么都不做。当我取消注释此行时,up()开始工作。这里奇怪的是我没有以任何方式使用这个变量。你能解释一下这种行为吗?

2 个答案:

答案 0 :(得分:3)

当您设置document.body.innerHTML = '';时,您将从 DOM树中删除<body>的所有子节点,但不会破坏这些节点本身的树结构。如果没有对这些节点的引用,它们也会被销毁并收集垃圾。

您已设置(全局) lower = document.getElementById('lower');,因此存在对<div id="lower">的引用,这意味着虽然它可能会从 DOM树中删除< / em>,它不会被破坏或被垃圾收集,因为它被这个引用“保持活着”。

现在出现了奇怪的东西,因为你将 String 方法(.innerHTML)与 DOM 方法混合在一起(getElementById,{{ 1}}),浏览器不确定从垃圾收集中保存什么。它最终决定appendChild引用的节点可以保留,但childNodes s不是足够强的键,因此被破坏。这意味着你不能统一获得parentNode,你也可以获得

null

当您设置(全局) Uncaught Error: NotFoundError: DOM Exception 8 时,这会保存upper,因为您现在有一个引用使其保持活动状态。它还会保存<div id="upper">,因为<div id="lower">的{​​{1}}也可以免受垃圾回收。这会保留它们之间的 childNode / upper链接。


值得注意的是,childNode可能会导致 id 属性冲突,因为 id 必须是唯一的,但根据定义,克隆不是唯一的

答案 1 :(得分:1)

您创建一个名为 upper 的全局变量。当您运行 crop 时,您将为id upper 的元素分配一个引用,该元素存储为全局,并且仍然可用作引用该元素的全局变量,无论您是什么做DOM。

修改

为了进一步解释,通过保留 upper ,您还保留其所有后代及其关系,因此在清除正文后 lower.parentNode 仍然存在。但是如果你没有保留对 upper 的引用,那么清除正文也删除 lower 的任何父级或兄弟,但不删除 lower 的后代