如何使用jQuery UI Sortable正确交叉?

如何使用jQuery UI Sortable正确交叉?

问题描述:

这是我尝试动画jQuery UI Sortable:

https:// codepen .io / anon / pen / YdMOXE

Here's my attempt at animating jQuery UI Sortable:
https://codepen.io/anon/pen/YdMOXE

var startIndex, changeIndex, uiHeight;

$('ul').sortable({
    'placeholder': 'marker',
    start: function(e, ui) {

        startIndex = ui.placeholder.index();
        uiHeight = ui.item.outerHeight(true);//get offset incl margin

        ui.item.nextAll('li:not(.marker)').css({
            transform: 'translateY(' +uiHeight+ 'px)'
        });

        ui.placeholder.css({
            height: 0,
            padding: 0
        });
    },
    change: function(e, ui) {

        changeIndex = ui.placeholder.index();


        if (startIndex > changeIndex) {

            var slice = $('ul li').slice(changeIndex, $('ul li').length);

            slice.not('.ui-sortable-helper').each(function() {
                var item = $(this);
                item.css({
                    background:'lightcoral',
                    transform: 'translateY(' +uiHeight+ 'px)'
                });
            });

        } else if (startIndex < changeIndex) {

            var slice = $('ul li').slice(startIndex, changeIndex);

            slice.not('.ui-sortable-helper').each(function() {
                var item = $(this);
                item.css({
                    background: 'lightgreen',
                    transform: 'translateY(0px)'
                });
            });
        }

        startIndex = changeIndex
    },
    stop: function(e, ui) {
        $('.ui-sortable-handle').css({
            background: 'lightblue',
            transform: 'translateY(0)'
        })
    }
});

不幸的是,它不能可靠地与容差:intersect 。 (当元素的 50%重叠时排序以进行更改)。它似乎只想通过指针位置排序。附件是一个视频来展示这一点。 https://gfycat.com/WatchfulPresentHedgehog

Unfortunately it does not work reliably with tolerance: intersect. (sorting to change when 50% of the element is overlapping). It seems to want to sort only via pointer location. Attached is a video to show this. https://gfycat.com/WatchfulPresentHedgehog

如何让它与交叉正常工作?

How do I get this to work correctly with intersect?

你可以看到 错误#8342

You can see the bug #8342


可排序:可排序选项的行为(或不正确的文档)容差:'intersect'

我已经测试过现在的解决方法(来自 此答案 (我已经更正了)垂直使用)和 此答案 ),这些内容在Munim Munna评论和两个变通方法中都有关联不能正常工作(非常非常错误)。

I have tested now workarounds (from this answer (I have corrected it for vertical using) and from this answer) which were linked in Munim Munna comment and both workarounds do not work correctly (very very buggy).

您必须设置容差:'指针'以及 cursorAt:{top:height / 2,left:width / 2} (可拖动元素的宽度和高度的一半)。

You have to set tolerance: 'pointer' along with cursorAt: {top: height/2, left: width/2} (the half size from the width and height of your draggable element).

tolerance:'pointer'选项允许元素在光标进入目标元素后立即替换目标元素。默认情况下,它被设置为 tolerance:'intersect'这意味着该项目与其他项目重叠至少50%。但遗憾的是这个选项存在一个错误(请参阅我的回答顶部)。

tolerance : 'pointer' option allows the element to replace the target element immediately as soon as the cursor enters the target element. By default it was setted to tolerance : 'intersect' which means that the item overlaps the other item by at least 50%. But unfortunately there is a bug for this option (see the top of my answer).

尝试使用和不使用 cursorAt 选项或更改值。此选项可移动排序元素或帮助程序,以便始终显示光标从同一位置拖动。坐标可以使用一个或两个键的组合作为哈希值给出: {top,left,right,bottom}

Try also to use it with and without cursorAt option or to change the value. This option moves the sorting element or helper so the cursor always appears to drag from the same position. Coordinates can be given as a hash using a combination of one or two keys: {top, left, right, bottom}.

以下是 容忍度>的文档code>选项 以及 cursorAt 选项

Here is the documentation for tolerance option and for cursorAt option.

从29.01.2019更新

我已经修复了jQuery UI Sortable中的一些错误:从上一个项目拖动它是否有足够的移动空间。我已修复此错误并添加此代码:

I have fixed some bugs from jQuery UI Sortable: on dragging from last item if after it it has not enough space for moving. I have fixed this bug with adding this code:

<div style="clear: both; line-height: 500px">&nbsp;</div>

直接在可排序元素之后。

directly after sortable element.

var startIndex, changeIndex, uiHeight,
    bRect = $("ul li")[0].getBoundingClientRect(),
    width = bRect.right - bRect.left,
    height = bRect.bottom - bRect.top;

$('ul').sortable(
{
    tolerance: 'pointer',
    cursorAt: {top: height/2, left: width/2}, //try to use it with and without this option
    'placeholder': 'marker',
    start: function(e, ui)
    {
        startIndex = ui.placeholder.index();
        uiHeight = ui.item.outerHeight(true); //get offset incl margin

        ui.item.nextAll('li:not(.marker)').css({
            transform: 'translateY(' + uiHeight + 'px)'
        });
        ui.placeholder.css({height:0, padding:0});
    },

    change: function(e, ui)
    {
        changeIndex = ui.placeholder.index();

        if(startIndex > changeIndex)
        {
            var slice = $('ul li').slice(changeIndex, $('ul li').length);

            slice.not('.ui-sortable-helper').each(function()
            {
                var item = $(this);
                item.css({
                    background:'lightcoral',
                    transform: 'translateY(' +uiHeight+ 'px)'
                });
            });
        }
        else if(startIndex < changeIndex)
        {
            var slice = $('ul li').slice(startIndex, changeIndex);
            slice.not('.ui-sortable-helper').each(function()
            {
                var item = $(this);
                item.css({
                    background: 'lightgreen',
                    transform: 'translateY(0px)'
                });
            });
        }

        startIndex = changeIndex
    },

    stop: function(e, ui)
    {
        $('.ui-sortable-handle').css({
            background: 'lightblue',
            transform: 'translateY(0)'
        })
    }
});

body{color:white; font-family:Helveticasans-serif; padding:10px}
ul{float:left; width:300px; border-radius:6px}
ul:after{clear:both; content:''; display:table}
li
{
    background: lightblue;
    display: block;
    position: relative;
    padding: 80px 6px;
    z-index: 1;
    margin: 5px 20px;
    overflow: hidden;
    transition: transform .2s
}
.marker{opacity:0.0; transition:.2s height}
.ui-sortable-helper{transform:scale(.9)}

<br><br>
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
</ul>
<!--
Fixing some bugs from jQuery UI Sortable:
on dragging from last item if after it
it has not enough space for moving
-->
<div style="clear: both; line-height: 500px">&nbsp;</div>
<!--END of Fixing bugs-->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>

在整页中查看此代码段更为有用(使用片段右侧顶部的链接)。

It is more useful to see this code snippet in full page (use the link at top of the right from snippet).