Переместить элемент списка в начало неупорядоченного списка с помощью jQuery
Допустим, у меня есть следующий неупорядоченный список
<ul>
<li><a>Hank</a></li>
<li><a>Alice</a></li>
<li><a>Tom</a></li>
<li><a>Ashlee</a></li>
</ul>
Что я ищу, когда я нажимаю на Tom, что он перемещается (анимируется и не перетаскивается) в начало списка (индекс 0).
Ive рассмотрел сортировку jquery, но я не могу найти способ программно активировать подвижную часть.
Ответы
Ответ 1
Я придумал решение, которое работает очень хорошо. Это доказательство концепции, поэтому вам, вероятно, придется немного изменить его, чтобы лучше работать для вашего конкретного случая. Кроме того, я только тестировал его в Firefox, но я не вижу причин, почему это не будет работать во всех браузерах. Во всяком случае, вот оно:
<script type="text/javascript">
$(document).ready(function() {
$('li').click(function() {
// the clicked LI
var clicked = $(this);
// all the LIs above the clicked one
var previousAll = clicked.prevAll();
// only proceed if it not already on top (no previous siblings)
if(previousAll.length > 0) {
// top LI
var top = $(previousAll[previousAll.length - 1]);
// immediately previous LI
var previous = $(previousAll[0]);
// how far up do we need to move the clicked LI?
var moveUp = clicked.attr('offsetTop') - top.attr('offsetTop');
// how far down do we need to move the previous siblings?
var moveDown = (clicked.offset().top + clicked.outerHeight()) - (previous.offset().top + previous.outerHeight());
// let move stuff
clicked.css('position', 'relative');
previousAll.css('position', 'relative');
clicked.animate({'top': -moveUp});
previousAll.animate({'top': moveDown}, {complete: function() {
// rearrange the DOM and restore positioning when we're done moving
clicked.parent().prepend(clicked);
clicked.css({'position': 'static', 'top': 0});
previousAll.css({'position': 'static', 'top': 0});
}});
}
});
});
</script>
<ul>
<li><a>Hank</a></li>
<li><a>Alice</a></li>
<li><a>Tom</a></li>
<li><a>Ashlee</a></li>
</ul>
Он вычисляет разницу в смещениях между нажатыми LI
и first LI
и перемещает щелкнутый вверх, устанавливая его position
на relative
и анимируя свойство top
. Аналогично, он вычисляет, сколько места осталось после щелчка LI
и соответственно перемещает все предыдущие. Когда это происходит с анимацией, он переупорядочивает DOM, чтобы соответствовать новому порядку и восстанавливает стили позиционирования.
Надеюсь, что это поможет!
Ответ 2
Нашел это еще опереже:
$('li').on('click', function() {
$(this).parent().prepend(this);
});
Живой пример
Ответ 3
Предполагая, что:
<ul id="list">
<li><a>Hank</a></li>
<li><a>Alice</a></li>
<li><a>Tom</a></li>
<li><a>Ashlee</a></li>
</ul>
то
$("#list a").click(function() {
$(this).parent().before("#list a:first");
return false;
});
Если вы хотите анимировать, то это немного сложнее. Один из вариантов:
$("#list a").click(function() {
$(this).parent().slideUp(500).before("#list a:first").slideDown(500);
return false;
});
Другая опция:
$("#list a").click(function() {
var item = $(this).parent();
var prev = item.prev();
while (prev.length > 0) {
item.before(prev);
prev = item.prev();
}
return false;
});
но я сомневаюсь, что вы получите гладкую анимацию таким образом.
Ответ 4
Я играл со скрипкой No Surprises и расширил код для замены двух произвольных наборов элементов (единственным ограничением является то, что они должны непосредственно следовать друг за другом).
см. здесь: http://jsfiddle.net/ZXYZ3/139/
Ответ 5
Я придумал это решение: http://jsfiddle.net/FabienDemangeat/TBYWw/
Идея состоит в том, чтобы выбрать индекс элемента Li, который будет перемещаться, и его назначение.
Если значение назначения уступает индексу элемента li для перемещения, эффект будет отменен.
Некоторые части не идеальны, но это может быть начальная точка. Я вдохновил себя на фрагмент, предоставленный "Без сюрпризов"
Основная функция swapLiElements
заменяет два элемента li и функцию обратного вызова, так как параметры позволяют легко выполнять несколько обменов (см. скрипку).
function swapLiElements($northLi, $southLi, isPushingDown, duration, easing, callbackFunction) {
var movement = $northLi.outerHeight();
// Set position of the li elements to relative
$northLi.css('position', 'relative');
$southLi.css('position', 'relative');
// Set the z-index of the moved item to 999 to it appears on top of the other elements
if(isPushingDown)
$northLi.css('z-index', '999');
else
$southLi.css('z-index', '999');
// Move down the first li
$northLi.animate({'top': movement}, {
duration: duration,
queue: false,
easing: easing,
complete: function() {
// Swap the li in the DOM
if(isPushingDown)
$northLi.insertAfter($southLi);
else
$southLi.insertBefore($northLi);
resetLiCssPosition($northLi);
resetLiCssPosition($southLi);
callbackFunction();
}
});
$southLi.animate({'top': -movement}, {
duration: duration,
queue: false,
easing: easing,
});
}