4

次の HTML と JavaScript は、この jsFiddle の一部から取得されます: http://jsfiddle.net/stephenjwatkins/2j3ZB/3/

HTML:

<p class="source">
    Source
</p>
<div id="target">
    <p class="dummy">
        Target
    </p>
</div>
<button id="transfer-button">Transfer</button>

JavaScript:

var sourceEl = $('.source');
var targetEl = $('#target');

$('#transfer-button').click(function() {
    targetEl.html('<p class="dummy">Transferring...</p>');
    setTimeout(function() {
        // Source element will be empty on second attempt to append
        targetEl.html('').append(sourceEl);
    }, 750);
    return false;
});​

setTimeout とダミー テキストは、単に視覚的なインジケータのためにあることに注意してください。

ご覧のとおり、ソース要素が DOM に追加され、DOM から削除された後、IE (すべてのバージョン) は、その後の追加時に空の要素を DOM に追加します。一方、他のすべてのブラウザーは、正しい空でない要素を追加します。

混乱を招くもう 1 つの側面は、sourceEl がまだ要素情報を持っていることです (たとえば、sourceEl.attr('class')"source" が返されます)。

この問題を軽減する方法 (例: ) は知ってsourceEl.clone()いますが、今後関連する問題を回避するために、IE の動作が異なる理由をよりよく理解することをお勧めします。

要素を一度置き換えた後、ソース要素がIEで一意に空になる原因は何ですか?

4

2 に答える 2

7

まず、重要な部分を強調しましょう。

  1. (最初のクリック)要素を取得し、source要素内に配置しtargetます。
  2. (2回目のクリック)target要素を空にし、新しい子()を追加して、DOMからp.dummy効果的に削除します。source
  3. 要素を空にして、DOMに存在しなくなったtargetを再追加しようとします。source

一見すると、source要素はすでにDOMから削除されているため、これはどのブラウザでも機能しません。ここでの「魔法」はJavaScriptのガベージコレクターです。ブラウザーは、それsourceElがまだスコープされていることを確認し(クロージャー内)、 jQueryオブジェクトsetTimeout内で参照されているDOM要素を破棄しません。sourceEl

ここでの問題は、JScript(MicrosftのJavascript実装)のガベージコレクターではなく、要素のを設定するときにJScriptがDOM解析を処理する方法innerHTMLです。

他のブラウザは、すべてのsをデタッチしchildNode(アクティブな参照がなくなるとGCによって収集されます)、渡されたhtml文字列をDOM要素に解析してそれらをDOMに追加します。一方、Jscriptは、切り離されたchildNodes' innerHTML/ childNodesも消去します。イラストについては、このフィドルを確認してください。

実際、この要素はIEにまだ存在しており、DOMに追加されます。

ここに画像の説明を入力してください

もうsはありchildNodeません。

この種の動作を防ぐために、要素を「上書き」する代わりに再利用する場合は.clone()、要素(質問で述べたように)またはその親.detach()を呼び出す前の要素。.html()

これは、要素が上書きされる前に使用するフィドル.detach()であり、すべてのブラウザで正常に機能します。

于 2012-08-25T05:17:45.627 に答える
2

私の考えでは、IE は正しく動作しており、他のブラウザーは魔法のように機能しています。それはすべて、次の行を呼び出すときに発生します。

targetEl.html('<p class="dummy">Transferring...</p>');

sourceElこれにより、要素がページから削除されます。したがって、それはもう存在しません。DOM オブジェクトを参照する変数がまだあるため、他のブラウザは DOM オブジェクトを記憶していると思います。しかし、IE はこれをページ上に存在しないと認識するため、参照を失います。

おっしゃったように、クリックしたときにオブジェクトを複製することをお勧めします。これにより、JavaScript で新しいオブジェクトが作成されます。幸いなことに、同じ変数を上書きしても機能します。

    sourceEl = sourceEl.clone();

http://jsfiddle.net/AbJQE/3/

editこの新しいソース オブジェクトを挿入する前に、既存の元のソース オブジェクトを削除することもできます。これにより、トリガー ハッピー クリッカーの問題が修正されます。

setTimeout(function() {
    $('.source').remove();
    targetEl.html('').append(sourceEl);
}, 750);
于 2012-08-25T04:39:47.807 に答える