3

この単純なページを考えてみましょう:

<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 の親を表示 ( upperdiv) することです。私の最初の試みでは、 を使用しようとしましたがlower.parentNode、それは であるため機能しませんnulllowerこれは、変数が本体の一部ではない DOM 要素を指しているためだと思います。(私の理解は正しいですか?)しかし、コメント行を考えてみましょう:

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

上位のdivへの参照を取得するだけです。この行のコメントを外すと、up()作業が開始されます。ここで奇妙なのは、この変数をまったく使用していないことです。この振る舞いを説明できますか?

4

2 に答える 2

3

を設定document.body.innerHTML = '';すると、 のすべての子ノードがDOM ツリー<body>から削除されますが、それらのノード自体のツリー構造は破壊されません。これらのノードへの参照が存在しない場合、それらも破棄され、ガベージ コレクションが行われます。

(global) を設定lower = document.getElementById('lower');したため、 への参照が存在します。これは、 DOM ツリー<div id="lower">から削除される可能性がありますが、この参照によって「存続」しているため、破棄またはガベージ コレクションが行われないことを意味します。

Stringメソッド ( .innerHTML) とDOMメソッド ( getElementById、 ) を混在させているためappendChild、ブラウザーはガベージ コレクションから何を保存するかを判断できません。childNodes参照されたノードはとどまることができると判断することになりますが、 parentNodes は十分に強力な結合ではないため、破壊されます。これは、一様に を取得できないことを意味しnull、取得することもできます

Uncaught Error: NotFoundError: DOM Exception 8 

(global) を設定すると、 がupper保存さ<div id="upper">れます。これは、参照を維持するためです。もガベージ コレクションから保護されているため<div id="lower">、も節約されます。これにより、それらの間のchildNode /リンクが保持されます。upperchildNodeparentNode


また、id は unique でなければならないため、id属性競合cloneNodeが発生する可能性があることにも注意してください。ただし、定義上、クローンは unique ではありません

于 2013-06-25T22:05:43.133 に答える
1

upperというグローバル変数を作成します。cropを実行すると、id upperの要素への参照が割り当てられます。これはグローバルとして格納され、DOM に対して何を行っても、その要素を参照するグローバル変数として引き続き使用できます。

編集

さらに説明すると、upperを保持することで、そのすべての子孫とその関係も保持されるため、 body をクリアした後もlower.parentNodeが引き続き存在します。ただし、 upperへの参照を保持しない場合、本体をクリアすると、 lowerの親または兄弟も削除されますが、 lowerの子孫は削除されません。

于 2013-06-25T22:02:27.887 に答える