Подтвердить что ты не робот

Переместить элемент списка в начало неупорядоченного списка с помощью 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, но я не могу найти способ программно активировать подвижную часть.

4b9b3361

Ответ 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,
    });

}