0

私が知る限り、この問題はここで説明されている問題と似ています。しかし、私は mootools を使用しておらず、私の質問と結果は異なります。これは、問題を実証するためのテスト ページです: http://jsfiddle.net/S7rtU/2/

createElementと を使用してコンテナに要素を追加しappendChildます。それぞれを追加するときに、それへの参照もプライベート配列 ( elems) に格納します。

次に、コンテナをクリアすることにし、 を設定してクリアしますcontainer.innerHTML = ''

(私の例では、最初に保留中のメッセージに設定し、次に を使用して 3 秒後setTimeoutにクリアします。これは、DOM への変更を観察する時間を与えるためです。)

次に、格納されている各要素をelems呼び出して、配列からコンテナーを再設定しようとします。container.appendChild

手元にあるブラウザーでテストしました: Firefox 17.0.1、Chrome 23.0.1271.97、Safari 3.1.2、IE 6、IE 7 。したがって、それらはメモリに正常に格納され、参照は破棄されません。さらに、これらの要素に登録されたイベント ハンドラーは引き続き機能します。

IE では、要素は再表示されません。

他のSOの質問を含め、この問題について私が読んだことはinnerHTML、コンテナを変更すると参照が壊れることになっていることを示唆しているようです。イベントハンドラーも壊れているはずです。ただし、私がテストした 3 つの最新のブラウザーでは、参照もイベント ハンドラーも壊れません。

もちろん、これを IE で機能させるには、次のようなものを使用できますが、多くの要素がある場合、これはかなりの余分な処理になります。

function explicitClearContainer() {
    var e;
    // Explicitly remove all elements
    for (var i = 0; i < elems.length; ++i) {
        e = elems[i];
        // Update the reference to the removed Node
        elems[i] = e.parentNode.removeChild(e);
    }
}

私の質問は、この動作について何がわかっているか、さまざまな環境で何が予想されるか、この種の手法を使用する際の落とし穴は何かということです。

コメントをいただければ幸いです。

4

1 に答える 1

0

innerHTML プロパティは、HTML5 で「標準化」されただけで、実際には、多くの機能に対する一般的なブラウザーの動作が文書化されています。innerHTML などはブラウザごとに実装が異なり、しばらくの間は引き続き異なるため、問題が発生している場合は使用しないことをお勧めします。

要素の子ノードをクリアする方法は他にもあります。

function removeContent(element) {
  while (element.firstChild) {
    element.removeChild(element.firstChild);
  }
}

これにより、innerHTML の問題が回避され、バージョンよりもコードが少し少なくなります。elementそれ自体の浅いクローンに置き換えることもできますが、それによって他の問題が発生する可能性があります。

于 2013-01-15T02:03:52.463 に答える