14

オプションのjQuery UIドキュメントの一部を次に示します。tolerance

これは、ドラッグ中の並べ替えの動作です。可能な値: 'intersect'、'pointer'。一部の設定では、「ポインター」の方がより自然です。

交差: ドラッグ可能なものはドロップ可能なものと少なくとも 50% オーバーラップします

デフォルトは ですがintersect、マウス ポインターが並べ替え可能なアイテムの上にない場合、ドラッグされた要素が別の並べ替え可能なアイテムの上に少なくとも 50% ある場合でも、並べ替えは行われません (私が期待する機能)。よく(上にリンクされています)

これは jQuery UI のバグですか、それとも理解が間違っていますか?

4

6 に答える 6

26

同じ問題を抱えている人のために、私が使用する回避策は次のとおりです。

$('#sortable').sortable({
    axis: 'x',
    sort: function (event, ui) {
        var that = $(this),
            w = ui.helper.outerWidth();
        that.children().each(function () {
            if ($(this).hasClass('ui-sortable-helper') || $(this).hasClass('ui-sortable-placeholder')) 
                return true;
            // If overlap is more than half of the dragged item
            var dist = Math.abs(ui.position.left - $(this).position().left),
                before = ui.position.left > $(this).position().left;
            if ((w - dist) > (w / 2) && (dist < w)) {
                if (before)
                    $('.ui-sortable-placeholder', that).insertBefore($(this));
                else
                    $('.ui-sortable-placeholder', that).insertAfter($(this));
                return false;
            }
        });
    },
});​

これは、水平方向のソート可能で、垂直方向のソート可能でどこにでも変更outerWidthできます。outerHeightposition.leftposition.top

ここに完全な作業例があります

于 2012-05-22T09:30:46.020 に答える
5

並べ替え可能なアイテムのサイズが不均一なため、状況が悪化します。ハンドラーの下部が子の下部を通過すると (下に移動するとき)、上部についても同じように順序を変更するように、dioslaska のコードを変更しました ...

sort: function (event, ui) {
    var that = $(this),
        draggedHeight = ui.helper.outerHeight(),
        originalTop = ui.originalPosition.top,
        draggedTop = ui.helper.position().top,
        draggedBottom = draggedTop + draggedHeight;
    that.children().each(function () {
        if ($(this).hasClass('ui-sortable-helper') || $(this).hasClass('ui-sortable-placeholder')) {
            return true;
        }
        var childTop = $(this).position().top,
            childHeight = $(this).outerHeight(),
            childBottom = childTop + childHeight,
            isChildAfter = originalTop < childTop,
            largeTop,largeBottom,smallTop,smallBottom;
        if (childHeight > draggedHeight) {
            largeTop = childTop;
            largeBottom = childTop + childHeight;
            smallTop = draggedTop;
            smallBottom = draggedBottom;
        } else {
            smallTop = childTop;
            smallBottom = childTop + childHeight;
            largeTop = draggedTop;
            largeBottom = draggedBottom;
        }
        if (smallBottom > largeTop || smallTop < largeBottom) {
            if (isChildAfter && draggedBottom >= childBottom) {
                $('.ui-sortable-placeholder', that).insertAfter($(this));
            } else if (!isChildAfter && draggedTop <= childTop) {
                $('.ui-sortable-placeholder', that).insertBefore($(this));
                return false;
            }
        }
    });
}

大きなアイテムを小さなアイテムの上にドラッグしたり、その逆を行ったりする可能性があるため、オーバーラップ検出が以前よりも少しトリッキーになっていることがわかります。

完璧ではありませんが、デフォルトの機能よりも大幅に改善されています。

于 2012-11-15T00:04:57.170 に答える
3

これは、ピタゴラスの定理と比較された要素の中心間の距離に基づくグリッド レイアウトsortのメソッドの実装です。

$("#sortable").sortable({
    ...
    sort: sort_jQueryBug8342Fix
});

function sort_jQueryBug8342Fix(e, ui) {

    // ui-sortable-helper: element being dragged
    // ui-sortable-placeholder: invisible item on the original place of dragged item
    var container = $(this);
    var placeholder = container.children('.ui-sortable-placeholder');

    var draggedCenterX = ui.helper.position().left + ui.helper.outerWidth()/2;
    var draggedCenterY = ui.helper.position().top + ui.helper.outerHeight()/2;

    container.children().each(function () {
        var item = $(this);

        if(!item.hasClass( 'ui-sortable-helper' ) && !item.hasClass( 'ui-sortable-placeholder' ) ) {
            var itemCenterX = item.position().left + item.outerWidth()/2;
            var itemCenterY = item.position().top + item.outerHeight()/2;

            // Pythagorean theorem
            var distanceBetweenCenters = Math.sqrt(Math.pow(itemCenterX - draggedCenterX, 2) + Math.pow(itemCenterY - draggedCenterY, 2));

            var minDimension = Math.min(item.outerWidth(), item.outerHeight(), ui.helper.outerWidth(), ui.helper.outerHeight());
            var overlaps = distanceBetweenCenters < (minDimension / 2);

            if (overlaps) {
                if (placeholder.index() > item.index()) {
                    placeholder.insertBefore(item);
                } else {
                    placeholder.insertAfter(item);
                }
                container.sortable('refreshPositions');
                return false;
            }

        }
    });
}

グリッド レイアウトや、4:3 または 16:10 の比率の画像サムネイルなど、幅と高さのサイズが近いアイテムに最適です。この場合、並べ替えをトリガーするには、50 ~ 60% のオーバーラップが必要です。300x50 ピクセル (または異なるサイズの要素) のような非常に幅の広い要素がある場合、それも機能すると思いますが、90% のように X 軸でさらにオーバーラップする必要があります。

注: Dropzone.js 要素を並べ替える場合は、最初のステートメント&& item.hasClass('dz-preview')に追加する必要があります。if

于 2016-07-08T21:29:58.060 に答える
3

これは @dioslaska の関数への追加です。グリッドで並べ替える必要がある場合 (要素がフローティングされている場合など)、子要素の上部の位置をチェックして、次のように同じ「行」にあるかどうかを確認できます。

sort: function (event, ui) {
  var self = $(this),
      width = ui.helper.outerWidth(),
      top = ui.helper.position().top;//changed to ;

  self.children().each(function () {
    if ($(this).hasClass('ui-sortable-helper') || $(this).hasClass('ui-sortable-placeholder')) {
      return true;
    }
    // If overlap is more than half of the dragged item
    var distance = Math.abs(ui.position.left - $(this).position().left),
        before = ui.position.left > $(this).position().left;

    if ((width - distance) > (width / 2) && (distance < width) && $(this).position().top === top) {
      if (before) {
        $('.ui-sortable-placeholder', self).insertBefore($(this));
      } else {
        $('.ui-sortable-placeholder', self).insertAfter($(this));
      }
      return false;
    }
  });
}
于 2013-05-14T14:13:23.953 に答える
1

これは、IE9、FF11、および Chrome18 で説明したとおりに発生します。

マウスが少なくとも 50% 上にある場合にオーバーラップを交差させます。
これは正しくないドキュメントだと思います。

編集: JQuery Bugtracker でこれに関連するバグは見つかりませんでした。

于 2012-05-17T14:28:30.643 に答える