Есть ли собственная функция jQuery для переключения элементов?
могу ли я легко поменять два элемента с помощью jQuery?
Я ищу, чтобы сделать это с одной строкой, если это возможно.
У меня есть элемент select, и у меня есть две кнопки для перемещения вверх или вниз по параметрам, и у меня уже есть выбранные и селекторы назначения на месте, я делаю это с помощью if, но мне было интересно, есть ли более простой способ.
20 ответов:
Я нашел интересный способ решить эту проблему, используя только 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); }
нет, нет, но вы могли бы взбить один:
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 элементу каждый, в противном случае это может дать странные результаты.
есть много пограничных случаев к этой проблеме, которая не обрабатывается ответ принято отвечать или bobince по. Другие решения, связанные с клонированием, находятся на правильном пути, но клонирование является дорогостоящим и ненужным. Мы испытываем соблазн клонировать, из-за вековой проблемы того, как поменять две переменные, в которой один из шагов должен назначить одну из переменных временной переменной. Задания, (клонирование), в этом случае не требуется. Вот основанный на 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) move
this
доthat
3) move
that
послеtemp
3b) удалить
temp
потом просто
$(selectorA).swapWith(selectorB);
вам не нужно два клона, один будет делать. Принимая Паоло Бергантино ответ у нас есть:
jQuery.fn.swapWith = function(to) { return this.each(function() { var copy_to = $(to).clone(true); $(to).replaceWith(this); $(this).replaceWith(copy_to); }); };
должно быть быстрее. Прохождение меньшего из двух элементов также должно ускорить процесс.
я использовал такую технику раньше. Я использую его для списка соединителей на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');
Я сделал функцию, которая позволяет перемещать несколько выбранные параметры вверх или вниз
$('#your_select_box').move_selected_options('down'); $('#your_select_boxt').move_selected_options('up');
зависимости:
$.fn.reverse = [].reverse; function swapWith() (Paolo Bergantino)
сначала он проверяет, может ли первый/последний выбранный параметр перемещаться вверх/вниз. Затем он перебирает все элементы и вызывает
swapWith(элемент.далее () или элемент.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
затем нужны только, если вы не можете гарантировать, что всегда есть элемент перед (в моем случае)
взгляните на плагин jQuery "Swapable"
http://code.google.com/p/jquery-swapable/
Он построен на "Сортируемом" и выглядит как сортируемый (drag-n-drop, placeholder и т. д.) но только поменять местами два элемента: перетаскивать. Все остальные элементы не затрагиваются и остаются на своем текущем положении.
это ответ на основе @lotifлогика ответа, но более обобщенное
если вы добавляете / добавляете После / До того, как элементы на самом деле двигался
=> клонирование не требуется
=> мероприятийесть два случая, которые могут произойти
- одна цель имеет что-то"
.prev()
ious " = > мы можем поставить другую цель.after()
что.- одна цель является первым ребенком его
.parent()
=> у нас можете.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>
Это мое решение для перемещения нескольких дочерних элементов вверх и вниз внутри родительского элемента. Хорошо работает для перемещения выбранных параметров в listbox (
<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, вы можете использовать этот метод
Я хотел, чтобы решение witch не использовало 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; };
он не должен использоваться с объектами jQuery, содержащими более одного элемента DOM
Если у вас есть несколько копий каждого элемента, вы должны сделать что-то в цикле, естественно. У меня недавно была такая ситуация. Два повторяющихся элемента, которые мне нужно было переключить, имели классы и контейнер 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")); });
Я сделал это с этот фрагмент
// Create comments var t1 = $('<!-- -->'); var t2 = $('<!-- -->'); // Position comments next to elements $(ui.draggable).before(t1); $(this).before(t2); // Move elements t1.after($(this)); t2.after($(ui.draggable)); // Remove comments t1.remove(); t2.remove();
Я сделал таблицу для изменения порядка obj в используемой базе данных .после. )(раньше (), так что это из того, что у меня есть эксперимент.
$(obj1).after($(obj2))
вставить obj1 перед obj2 и
$(obj1).before($(obj2))
сделать наоборот.
Так что если obj1 после obj3 и obj2 после obj4, и если вы хотите изменить место obj1 и obj2 вы будете делать это как
$(obj1).before($(obj4)) $(obj2).before($(obj3))
это должно помочь Кстати, вы можете использовать .prev () and .следующий() найти obj3 и obj4 если у вас не было какой-то индекс для него уже есть.
если nodea и nodeb являются братьями и сестрами, любит две
<tr>
в том же<tbody>
, вы можете просто использовать$(trA).insertAfter($(trB))
или$(trA).insertBefore($(trB))
поменять их, это работает для меня. и вам не нужно звонить$(trA).remove()
раньше, иначе вам нужно повторно привязать некоторые события щелчка на$(trA)
Я думаю, что вы можете сделать это очень просто. Например, допустим, у вас есть следующая структура: ...
<div id="first">...</div> <div id="second">...</div>
и результат должен быть
<div id="second">...</div> <div id="first">...</div>
jquery:
$('#second').after($('#first'));
Я надеюсь, что это помогает!