同様の質問がありますが、すべての答えは、内部のコンテンツに対してのみhtml要素を交換することです。
たくさんのコンテンツ(テーブル、選択ボックス、入力など)を含む2つのdivを交換する必要があります。要素にはイベントリスナーが含まれているため、メインのdivを交換した後にそれらを保持する必要があります。
jQuery1.5にアクセスできます。だからそれで答えは大丈夫です。
同様の質問がありますが、すべての答えは、内部のコンテンツに対してのみhtml要素を交換することです。
たくさんのコンテンツ(テーブル、選択ボックス、入力など)を含む2つのdivを交換する必要があります。要素にはイベントリスナーが含まれているため、メインのdivを交換した後にそれらを保持する必要があります。
jQuery1.5にアクセスできます。だからそれで答えは大丈夫です。
イベントハンドラーを失ったり、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/
これは、実際に要素をリロードせずに2つの要素を交換するためのより単純な関数です...
function swapElements(obj1, obj2) {
obj2.nextSibling === obj1
? obj1.parentNode.insertBefore(obj2, obj1.nextSibling)
: obj1.parentNode.insertBefore(obj2, obj1);
}
注:obj1にYouTubeのような埋め込みビデオがある場合、スワップ時にリロードされません。変更されたのは要素の位置だけです。
2つの要素のparentNodesと1つのnextSiblingを追跡している場合は、一時的なプレースホルダーなしで2つの要素を子と交換できます。
2番目の要素が一人っ子、またはその親の最後の子である場合、その置換は(適切に)親に追加されます。
function swap(a, b){
var p1= a.parentNode, p2= b.parentNode, sib= b.nextSibling;
if(sib=== a) sib= sib.nextSibling;
p1.replaceChild(b, a);
if(sib) p2.insertBefore(a, sib);
else p2.appendChild(a);
return true;
}
私の単純な関数は、最短で最も広く互換性があるようです。プレースホルダーやリロード要素など、面倒なものは必要ありません。
function swapElements(el1, el2) {
var p2 = el2.parentNode, n2 = el2.nextSibling
if (n2 === el1) return p2.insertBefore(el1, el2)
el1.parentNode.insertBefore(el2, el1);
p2.insertBefore(el1, n2);
}
これは、イベントがスワップしている要素にどのようにバインドされているかによって多少異なります。jQueryを使用している場合、本当に必要なのはこの答えだけです。
主なことは、要素delete
やremoveChildnode
要素ではなく、htmlをコピーして別の場所に貼り付けることです。そうすることで、一部のブラウザはすべてのリソース(イベントハンドラを含む)をクリアするため、バインドされたイベントは失われます。IEは、動的にバインドされたイベントに関してはメモリリークで有名ですが。実際、さまざまなブラウザがどのように動作するかを予測するのは困難です。
.live()
基本的には、HTML文字列のコピー/貼り付けを除いて、任意の方法で要素を交換し、jQueryのメソッドを使用してイベントをバインドします。.on
1.5には方法がないと思うので
jQueryは質問でタグ付けされているため、jQueryソリューションは次のとおりです。
$('#el_to_move').appendTo('#target_parent_el');
それでおしまい。jQueryはそれを切り取って新しい場所に貼り付けます。
これも役立つ可能性があります。
o1.swapNode(o2);という事実を考えると、これはすべて非常に奇妙です。IEでは非常に長い間うまく機能します。オブジェクトノードとテキストノードが混在している私の場合、1つのバージョンのみが機能します(すでにここに示されています):
let t = document.createElement("div");
o1.parentNode.insertBefore(t, o1);
o2.parentNode.insertBefore(o1, o2);
t.parentNode.insertBefore(o2, t);
t.parentNode.removeChild(t);
はい、一時ノードを作成するのは嫌いですが、このトリックのない上記のバージョンは、(関数を呼び出さずに)まっすぐに使用すると失敗します。関数を呼び出したくない場合があります。
要素を並べて交換する場合は、非常に簡単です。
<div class="container">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
</div>
$('.container .item:nth-child(2)').insertBefore('.container .item:nth-child(1)');