web-dev-qa-db-ja.com

jQueryはアニメーションで並べ替え可能

私は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)を見ると、私が話していることがわかります。

ありがとう。

19

パーティーに少し遅れましたが、このトピックに関するヘルプがほとんどなかったため、jQueryで解決策を見つけることにしました。特に、FacebookなどのWebアプリに存在する機能と、アルバムの画像をドラッグアンドドロップして並べ替えるために複製しました。それに伴うかわいいアニメーション...

だから私はかなりうまくいくように見える解決策を思いついた、そして私はそれを私の能力の及ぶ限りでは説明するために最善を尽くす!ここに行く...

ここでの最大の問題は、並べ替え可能な要素をアニメーション化するだけでなく、アニメーション化する必要がある場所を特定することでした。ギャラリー内の画像などのフローティング要素に関しては素晴らしいことです。これを回避するために、元のフローティングLIアイテムを.clone()し、クローンを絶対に配置することにしましたnderz-indexを使用して元のLIアイテム元のLIアイテムよりも小さい値で、jQueryソート可能オブジェクトからchangeイベントが発生すると、元の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);
            });
        }
    });
});

うわー、これが理にかなっていて、誰かが並べ替え可能なリストをアニメーション化するのに役立つことを本当に願っていますが、これは興味のある人にとっては実用的な例です! :)

26
Chris Kempen

クリスケンペンが言ったことを実装しただけです: 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);
        });
    }
});
17
yarden.refaeli

このソリューションは最初のトランジションを作成するのに最適ですが、アイテムがスナップバックすると、トランジションはありません。解決策は私が予想していたよりも簡単です。 .sortable()のrevertオプションを調整するだけです。

このような:

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

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

これにより、アイテムの新しい家にスムーズに移行できます。

jsFiddleの例はここをクリック

3
Elon Zito

JqueryuiでSortableを使用しなかったのはなぜですか? 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>
2
aavezel

上記の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);
    }
});
1
BoosterStage