2つのHTML要素を交換し、それらのイベントリスナーを保持する 質問する

2つのHTML要素を交換し、それらのイベントリスナーを保持する 質問する

同様の質問がありますが、回答はすべて、HTML 要素を内部のコンテンツのみと交換することに関するものです。

たくさんのコンテンツ (テーブル、選択ボックス、入力など) を含む 2 つの div を交換する必要があります。要素にはイベント リスナーがあるため、メインの div を交換した後もそれらを保持する必要があります。

私は jQuery 1.5 にアクセスできます。そのため、それを使用した回答は問題ありません。

ベストアンサー1

イベント ハンドラーを失ったり DOM 参照を壊したりせずに 2 つの div を交換するには、それらを DOM 内で移動するだけです。重要なのは、innerHTML を変更しないことです。変更すると、新しい DOM ノードが最初から再作成され、それらの DOM オブジェクトの以前のイベント ハンドラーがすべて失われるためです。

ただし、DOM 要素を DOM 内の新しい場所に移動するだけの場合は、DOM 要素自体は変更されずに DOM 要素の親が変更されるだけなので、すべてのイベントが添付されたままになります。

DOM 内の 2 つの要素を交換する簡単な関数を次に示します。一方が他方の子でない限り、任意の 2 つの要素で機能します。

function swapElements(obj1, obj2) {
    // create marker element and insert it where obj1 is
    var temp = document.createElement("div");
    obj1.parentNode.insertBefore(temp, obj1);

    // move obj1 to right before obj2
    obj2.parentNode.insertBefore(obj1, obj2);

    // move obj2 to right before where obj1 used to be
    temp.parentNode.insertBefore(obj2, temp);

    // remove temporary marker node
    temp.parentNode.removeChild(temp);
}

ここで動作を確認できます:http://jsfiddle.net/jfriend00/NThjN/


一時要素を挿入せずに動作するバージョンを次に示します。

function swapElements(obj1, obj2) {
    // save the location of obj2
    var parent2 = obj2.parentNode;
    var next2 = obj2.nextSibling;
    // special case for obj1 is the next sibling of obj2
    if (next2 === obj1) {
        // just put obj1 before obj2
        parent2.insertBefore(obj1, obj2);
    } else {
        // insert obj2 right before obj1
        obj1.parentNode.insertBefore(obj2, obj1);

        // now insert obj1 where obj2 was
        if (next2) {
            // if there was an element after obj2, then insert obj1 right before that
            parent2.insertBefore(obj1, next2);
        } else {
            // otherwise, just append as last child
            parent2.appendChild(obj1);
        }
    }
}

動作デモ:http://jsfiddle.net/jfriend00/oq92jqrb/

おすすめ記事