jQuery сортируется с анимацией - PullRequest
19 голосов
/ 21 февраля 2011

Я использую jQuery и Sortable, чтобы упорядочить свой список элементов (и это http://dragsort.codeplex.com).

Все отлично работает.

Я использую функцию для dragEnd, чтобы упорядочитьсписки по порядку.

Вот мой код:

$("#list1, #list2").dragsort({ dragSelector: "div",
                               dragBetween: true,
                               dragEnd: saveOrder,
                               placeHolderTemplate: "<li class='placeHolder'><div></div></li>" });

function saveOrder() {
    var data = $("#list1 li").map(function() { return $(this).children().html(); }).get();
    $("input[name=list1SortOrder]").val(data.join("|"));
};

Мой вопрос: есть ли способ сделать анимацию во время перетаскивания? Или изменить положение элементов при перетаскивании?Мне просто нужно, чтобы он работал в Safari.

Один из примеров:

http://www.youtube.com/watch?v=U3j7mM_JBNw

Посмотрите на перетаскивание (0:30), и выпосмотри, о чем я говорю.

Спасибо.

Ответы [ 5 ]

26 голосов
/ 16 ноября 2012

Немного опоздал на вечеринку, но я был полон решимости использовать решение с jQuery, так как в этом вопросе было очень мало помощи, особенно в том, что касается репликации функций, существующих в веб-приложениях, таких как Facebook, и перетаскивании изображений их альбомов. изменить порядок, и красивые анимации, которые сопровождают это ...

Итак, я нашел решение, которое, кажется, работает довольно хорошо, и я сделаю все возможное, чтобы объяснить его в меру своих способностей! Здесь идет ...

Самая большая проблема здесь заключалась в том, чтобы не только анимировать сортируемые элементы, но и выяснить, где их нужно анимировать - фантастика, когда речь идет о плавающих элементах, таких как изображения в галерее! Чтобы обойти это, я решил .clone() исходные плавающие LI предметы, расположить клонов абсолютно под исходных LI предметов, используя значение z-index, которое было меньше, чем исходное LI элементов, а затем, когда событие change сработало из сортируемой jQuery, я мог обнаружить положение оригинала LI и анимировать абсолютно позиционированные клоны в эти позиции. Остальное было просто показать / скрыть элементы соответствующим образом, чтобы получить желаемый эффект.

Вот код, начинающийся с HTML:

<ul id="original_items">
    <li><img src="something.jpg" /></li>
    <li><img src="something.jpg" /></li>
    <li><img src="something.jpg" /></li>
</ul>

<ul id="cloned_items">
</ul>

Итак, у нас есть оригинальные элементы, которые мы пытаемся отсортировать, и контейнер для клонированных элементов. Время для CSS:

#original_items, #cloned_items {
    list-style: none;
}

#original_items li {
    float: left;
    position: relative;
    z-index: 5;
}

#cloned_items li {
    position: absolute;
    z-index: 1;
}

С помощью нашего CSS мы просто удаляем любой стиль списка, плаваем наши оригинальные элементы и устанавливаем требования z-index, чтобы клонированные элементы находились под исходными элементами. Обратите внимание на положение relative на исходных элементах, чтобы убедиться, что они ведут себя как положено. Почему под тобой спросить? Это (надеюсь) станет ясным с некоторыми Javascript:

jQuery(function(){

    // loop through the original items...
    jQuery("#original_items li").each(function(){

        // clone the original items to make their
        // absolute-positioned counterparts...
        var item = jQuery(this);
        var item_clone = item.clone();
        // 'store' the clone for later use...
        item.data("clone", item_clone);

        // set the initial position of the clone
        var position = item.position();
        item_clone.css("left", position.left);
        item_clone.css("top", position.top);

        // append the clone...
        jQuery("#cloned_items").append(item_clone);
    });

    // create our sortable as usual...
    // with some event handler extras...
    jQuery("#original_items").sortable({

        // on sorting start, hide the original items...
        // only adjust the visibility, we still need
        // their float positions..!
        start: function(e, ui){
            // loop through the items, except the one we're
            // currently dragging, and hide it...
            ui.helper.addClass("exclude-me");
            jQuery("#original_items li:not(.exclude-me)")
                .css("visibility", "hidden");

            // get the clone that's under it and hide it...
            ui.helper.data("clone").hide();
        },

        stop: function(e, ui){
            // get the item we were just dragging, and
            // its clone, and adjust accordingly...
            jQuery("#original_items li.exclude-me").each(function(){
                var item = jQuery(this);
                var clone = item.data("clone");
                var position = item.position();

                // move the clone under the item we've just dropped...
                clone.css("left", position.left);
                clone.css("top", position.top);
                clone.show();

                // remove unnecessary class...
                item.removeClass("exclude-me");
            });

            // make sure all our original items are visible again...
            jQuery("#original_items li").css("visibility", "visible");
        },

        // here's where the magic happens...
        change: function(e, ui){
            // get all invisible items that are also not placeholders
            // and process them when ordering changes...
            jQuery("#original_items li:not(.exclude-me, .ui-sortable-placeholder)").each(function(){
                var item = jQuery(this);
                var clone = item.data("clone");

                // stop current clone animations...
                clone.stop(true, false);

                // get the invisible item, which has snapped to a new
                // location, get its position, and animate the visible
                // clone to it...
                var position = item.position();
                clone.animate({
                    left: position.left,
                    top:position.top}, 500);
            });
        }
    });
});

Ух ты, я действительно надеюсь, что это имеет смысл и помогает кому-то оживить свои сортируемые списки, но это рабочий пример для всех, кто заинтересован! :)

17 голосов
/ 16 марта 2013

Просто воплотил в жизнь то, что сказал Крис Кемпен: http://jsfiddle.net/dNfsJ/

jQuery(function(){

// loop through the original items...
jQuery("#original_items li").each(function(){

    // clone the original items to make their
    // absolute-positioned counterparts...
    var item = jQuery(this);
    var item_clone = item.clone();
    // 'store' the clone for later use...
    item.data("clone", item_clone);

    // set the initial position of the clone
    var position = item.position();
    item_clone.css("left", position.left);
    item_clone.css("top", position.top);

    // append the clone...
    jQuery("#cloned_items").append(item_clone);
});

// create our sortable as usual...
// with some event handler extras...
jQuery("#original_items").sortable({

    // on sorting start, hide the original items...
    // only adjust the visibility, we still need
    // their float positions..!
    start: function(e, ui){
        // loop through the items, except the one we're
        // currently dragging, and hide it...
        ui.helper.addClass("exclude-me");
        jQuery("#original_items li:not(.exclude-me)")
            .css("visibility", "hidden");

        // get the clone that's under it and hide it...
        ui.helper.data("clone").hide();
    },

    stop: function(e, ui){
        // get the item we were just dragging, and
        // its clone, and adjust accordingly...
        jQuery("#original_items li.exclude-me").each(function(){
            var item = jQuery(this);
            var clone = item.data("clone");
            var position = item.position();

            // move the clone under the item we've just dropped...
            clone.css("left", position.left);
            clone.css("top", position.top);
            clone.show();

            // remove unnecessary class...
            item.removeClass("exclude-me");
        });

        // make sure all our original items are visible again...
        jQuery("#original_items li").css("visibility", "visible");
    },

    // here's where the magic happens...
    change: function(e, ui){
        // get all invisible items that are also not placeholders
        // and process them when ordering changes...
        jQuery("#original_items li:not(.exclude-me, .ui-sortable-placeholder)").each(function(){
            var item = jQuery(this);
            var clone = item.data("clone");

            // stop current clone animations...
            clone.stop(true, false);

            // get the invisible item, which has snapped to a new
            // location, get its position, and animate the visible
            // clone to it...
            var position = item.position();
            clone.animate({
                left: position.left,
                top:position.top}, 500);
        });
    }
});
3 голосов
/ 30 января 2014

Хотя это решение прекрасно работает для создания начального перехода, когда элемент возвращается назад, перехода нет. Решение проще, чем я ожидал. Все, что вам нужно сделать, это настроить параметр revert в .sortable ()

Как это:

     <script>
      $(document).ready(function() {
        $( "#sortable" ).sortable({
         tolerance: 'pointer',
         revert: 'invalid'
        }).disableSelection();
      });
     </script>

API jQuery UI: http://api.jqueryui.com/sortable/#option-revert

Это делает приятный и плавный переход к новому дому предмета.

Нажмите здесь, чтобы получить ПРИМЕР на jsFiddle

2 голосов
/ 22 февраля 2011

Почему вы не использовали Sortable на jqueryui?http://jsfiddle.net/KgNCD/

JS:

$( "#sortable" ).sortable({       
    start: function(e, ui){
        $(ui.placeholder).hide(300);
    },
    change: function (e,ui){
        $(ui.placeholder).hide().show(300);
    }
});                           
$("#sortable").disableSelection();

HTML:

<ul id="sortable">
    <li class="ui-state-default">1</li>
    <li class="ui-state-default">2</li>
    <li class="ui-state-default">3</li>
    <li class="ui-state-default">4</li>
    <li class="ui-state-default">5</li>
    <li class="ui-state-default">6</li>
    <li class="ui-state-default">7</li>
    <li class="ui-state-default">8</li>
    <li class="ui-state-default">9</li>
    <li class="ui-state-default">10</li>
    <li class="ui-state-default">11</li>
    <li class="ui-state-default">12</li>
</ul>
1 голос
/ 15 февраля 2012

Из ответа jsfiddle выше (http://jsfiddle.net/KgNCD/2/):

$( "#sortable" ).sortable({       
    start: function(e, ui){
        $(ui.placeholder).hide(300);
    },
    change: function (e,ui){
        $(ui.placeholder).hide().show(300);
    }
});
...