2つの要素をjQueryで簡単に交換できますか?
可能であれば、1行でこれを実行することを検討しています。
select要素があり、オプションを上下に移動するための2つのボタンがあり、すでにselectセレクターとdestinationセレクターが配置されていますが、ifを使用していますが、もっと簡単な方法があるかどうか疑問に思っていました。
2つの要素をjQueryで簡単に交換できますか?
可能であれば、1行でこれを実行することを検討しています。
select要素があり、オプションを上下に移動するための2つのボタンがあり、すでにselectセレクターとdestinationセレクターが配置されていますが、ifを使用していますが、もっと簡単な方法があるかどうか疑問に思っていました。
回答:
jQueryのみを使用してこれを解決する興味深い方法を見つけました。
$("#element1").before($("#element2"));
または
$("#element1").after($("#element2"));
:)
パウロの言うとおりですが、なぜ彼が関係する要素を複製しているのかはわかりません。これは実際には必要ありません。要素とその子孫に関連付けられている参照やイベントリスナーは失われます。
プレーンなDOMメソッドを使用した非クローンバージョンを次に示します(jQueryには、この特定の操作を簡単にするための特別な関数がないため)。
function swapNodes(a, b) {
var aparent = a.parentNode;
var asibling = a.nextSibling === b ? a : a.nextSibling;
b.parentNode.insertBefore(a, b);
aparent.insertBefore(b, asibling);
}
いいえ、ありませんが、1つ上げることができます。
jQuery.fn.swapWith = function(to) {
return this.each(function() {
var copy_to = $(to).clone(true);
var copy_from = $(this).clone(true);
$(to).replaceWith(copy_from);
$(this).replaceWith(copy_to);
});
};
使用法:
$(selector1).swapWith(selector2);
これは、セレクターがそれぞれ1つの要素とのみ一致する場合にのみ機能することに注意してください。
この問題には、受け入れられた回答やボビンスの回答では処理されないエッジケースがたくさんあります。クローン作成を含む他のソリューションは正しい方向に進んでいますが、クローン作成は高価で不要です。2つの変数を交換する方法の古くからの問題があるため、クローンを作成したくなります。その1つは、変数の1つを一時変数に割り当てることです。この場合、割り当て(クローン)は必要ありません。ここにjQueryベースのソリューションがあります:
function swap(a, b) {
a = $(a); b = $(b);
var tmp = $('<span>').hide();
a.before(tmp);
b.before(a);
tmp.replaceWith(b);
};
これらの答えの多くは一般的なケースでは単に間違っていますが、実際に機能する場合でも不必要に複雑なものがあります。jQuery .before
と.after
メソッドは、やりたいことのほとんどを行いますが、多くのスワップアルゴリズムが機能するためには、3番目の要素が必要です。これは非常に単純です。移動する間、一時的なDOM要素をプレースホルダーとして作成します。両親や兄弟姉妹を見る必要はなく、確かにクローンを作成する必要もありません...
$.fn.swapWith = function(that) {
var $this = this;
var $that = $(that);
// create temporary placeholder
var $temp = $("<div>");
// 3-step swap
$this.before($temp);
$that.before($this);
$temp.after($that).remove();
return $this;
}
1)一時的なdivをtemp
前に置くthis
2)this
前に移動that
3)that
後に移動temp
3b)削除 temp
その後、単に
$(selectorA).swapWith(selectorB);
2つのクローンは必要ありませんが、1つは必要です。パオロベルガンティーノの答えを見てみましょう。
jQuery.fn.swapWith = function(to) {
return this.each(function() {
var copy_to = $(to).clone(true);
$(to).replaceWith(this);
$(this).replaceWith(copy_to);
});
};
より速くする必要があります。2つの要素のうち小さい方を渡すと、処理速度も向上します。
以前はこんなテクニックを使っていました。http://mybackupbox.comのコネクタリストに使用します
// clone element1 and put the clone before element2
$('element1').clone().before('element2').end();
// replace the original element1 with element2
// leaving the element1 clone in it's place
$('element1').replaceWith('element2');
end()
ですが、チェーンを継続しない場合は必要ありません。いかがですか$('element1').clone().before('element2').end().replaceWith('element2');
clone()
任意のjqueryのを保存していないdata()
ユーザーが指定しない限り、clone(true)
あなたがいない失うすべてのデータを行うので、あなたは、ソートしている場合、重要な区別を-
選択した複数のオプションを上下に移動できる機能を作りました
$('#your_select_box').move_selected_options('down');
$('#your_select_boxt').move_selected_options('up');
依存関係:
$.fn.reverse = [].reverse;
function swapWith() (Paolo Bergantino)
最初に、最初/最後に選択したオプションが上下に移動できるかどうかを確認します。次に、すべての要素をループして呼び出します
swapWith(element.next()またはelement.prev())
jQuery.fn.move_selected_options = function(up_or_down) {
if(up_or_down == 'up'){
var first_can_move_up = $("#" + this.attr('id') + ' option:selected:first').prev().size();
if(first_can_move_up){
$.each($("#" + this.attr('id') + ' option:selected'), function(index, option){
$(option).swapWith($(option).prev());
});
}
} else {
var last_can_move_down = $("#" + this.attr('id') + ' option:selected:last').next().size();
if(last_can_move_down){
$.each($("#" + this.attr('id') + ' option:selected').reverse(), function(index, option){
$(option).swapWith($(option).next());
});
}
}
return $(this);
}
クローンなしの他のもの:
スワップする実際の要素と名目上の要素があります。
$nominal.before('<div />')
$nb=$nominal.prev()
$nominal.insertAfter($actual)
$actual.insertAfter($nb)
$nb.remove()
その後insert <div> before
、remove
その後のみが必要です、あなたが確認できない場合は、常に前の要素があることを確認してください(私の場合はそうです)
.prev()
の長さ、および0場合、.prepend()
に.parent()
:)そうすれば、あなたは余分な要素を作成する必要はありません。
jQueryプラグイン「スワップ可能」を見てください
http://code.google.com/p/jquery-swapable/
「ソート可能」に基づいて構築されており、ソート可能(ドラッグアンドドロップ、プレースホルダーなど)のように見えますが、スワップとドラッグの2つの要素のみを交換します。他のすべての要素は影響を受けず、現在の位置にとどまります。
これは@lotifの回答ロジックに基づく回答ですが、少し一般化されています
要素が実際に移動さ
れる前/後に追加/前に追加する場合
=>クローンは不要
=>イベントが保持されます
.prev()
ious」がある=> もう1つのターゲットを置くことができ.after()
ます。.parent()
=> もう1つ.prepend()
のターゲットを親にすることができます。このコードはさらに短くすることもできますが、読みやすくするためにこのようにしています。親(必要な場合)と前の要素の事前保存は必須であることに注意してください。
$(function(){
var $one = $("#one");
var $two = $("#two");
var $onePrev = $one.prev();
if( $onePrev.length < 1 ) var $oneParent = $one.parent();
var $twoPrev = $two.prev();
if( $twoPrev.length < 1 ) var $twoParent = $two.parent();
if( $onePrev.length > 0 ) $onePrev.after( $two );
else $oneParent.prepend( $two );
if( $twoPrev.length > 0 ) $twoPrev.after( $one );
else $twoParent.prepend( $one );
});
...内部コードを関数に自由にラップしてください:)
サンプルのフィドルには、イベント保存を示すために追加のクリックイベントがアタッチされています...
サンプルのフィドル: https : //jsfiddle.net/ewroodqa/
...次のような場合でも、さまざまなケースで機能します。
<div>
<div id="one">ONE</div>
</div>
<div>Something in the middle</div>
<div>
<div></div>
<div id="two">TWO</div>
</div>
これは、親要素内で複数の子要素を上下に移動するための私の解決策です。リストボックス(<select multiple></select>
)で選択したオプションを移動するのに適しています
上に移動:
$(parent).find("childrenSelector").each((idx, child) => {
$(child).insertBefore($(child).prev().not("childrenSelector"));
});
下に移動:
$($(parent).find("childrenSelector").get().reverse()).each((idx, child) => {
$(opt).insertAfter($(child).next().not("childrenSelector"));
});
jQueryオブジェクトで選択された2つの項目を入れ替えたい場合は、このメソッドを使用できます
魔女がclone()を使用しない解決策が必要だった
jQuery.fn.swapWith = function(target) {
if (target.prev().is(this)) {
target.insertBefore(this);
return;
}
if (target.next().is(this)) {
target.insertAfter(this);
return
}
var this_to, this_to_obj,
target_to, target_to_obj;
if (target.prev().length == 0) {
this_to = 'before';
this_to_obj = target.next();
}
else {
this_to = 'after';
this_to_obj = target.prev();
}
if (jQuery(this).prev().length == 0) {
target_to = 'before';
target_to_obj = jQuery(this).next();
}
else {
target_to = 'after';
target_to_obj = jQuery(this).prev();
}
if (target_to == 'after') {
target.insertAfter(target_to_obj);
}
else {
target.insertBefore(target_to_obj);
}
if (this_to == 'after') {
jQuery(this).insertAfter(this_to_obj);
}
else {
jQuery(this).insertBefore(this_to_obj);
}
return this;
};
複数のDOM要素を含むjQueryオブジェクトでは使用しないでください
各要素のコピーが複数ある場合は、自然にループで何かを行う必要があります。最近このような状況になりました。私が切り替えるのに必要な2つの繰り返し要素には、クラスとコンテナーdivがありました。
<div class="container">
<span class="item1">xxx</span>
<span class="item2">yyy</span>
</div>
and repeat...
次のコードを使用すると、すべてを反復して逆にすることができます...
$( ".container " ).each(function() {
$(this).children(".item2").after($(this).children(".item1"));
});
私は.after().before()を使用してデータベースのobjの順序を変更するためのテーブルを作成したので、これは私が実験したものです。
$(obj1).after($(obj2))
obj2の前にobj1を挿入し、
$(obj1).before($(obj2))
逆も同様です。
したがって、obj1がobj3の後に、obj2がobj4の後にあり、場所obj1とobj2を変更したい場合は、次のようにします。
$(obj1).before($(obj4))
$(obj2).before($(obj3))
これはそれを行うはずですが、何らかの種類のインデックスがまだない場合は、.prev()と.next()を使用してobj3とobj4を見つけることができます。
$('.five').swap('.two');
このようなjQuery関数を作成します
$.fn.swap = function (elem)
{
elem = elem.jquery ? elem : $(elem);
return this.each(function ()
{
$('<span></span>').insertBefore(this).before(elem.before(this)).remove();
});
};
おかげヤニック・ギネスでhttps://jsfiddle.net/ARTsinn/TVjnr/
とても簡単にできると思います。たとえば、次の構造があるとします:...
<div id="first">...</div>
<div id="second">...</div>
そして結果は
<div id="second">...</div>
<div id="first">...</div>
jquery:
$('#second').after($('#first'));
お役に立てば幸いです。