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

时间:2019-01-16 22:06:36

标签: javascript jquery html jquery-ui jquery-ui-sortable

这是我对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)'
        })
    }
});

很遗憾,它不能与tolerance: intersect一起可靠地工作。 (当元素的50%重叠时排序以更改)。似乎只想通过指针位置进行排序。随附的视频显示了这一点。 https://gfycat.com/WatchfulPresentHedgehog

如何使它与相交正确工作?

1 个答案:

答案 0 :(得分:1)

您可以看到 the bug #8342

  

可解决:可排序选项tolerance: 'intersect'的错误行为(或错误文档)

我已经测试了以下链接的变通办法(来自 this answer (已针对垂直使用进行了更正)和来自 this answer 的) Munim Munna的评论,两种解决方法均无法正常运行(非常容易出问题)。

tolerance: 'pointer'的解决方法

您必须将tolerance: 'pointer'设置为cursorAt: {top: height/2, left: width/2}(可拖动元素的宽度和高度的一半大小)。

tolerance : 'pointer'选项允许元素在光标进入目标元素后立即替换目标元素。默认情况下,它设置为tolerance : 'intersect',这意味着该项目与另一项目重叠至少50%。但不幸的是,此选项有一个错误(请参见答案的顶部)。

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

这是 tolerance option cursorAt option 的文档。

从2019年1月29日更新

我修复了jQuery UI Sortable中的一些错误:从最后一项拖动,如果后面没有足够的移动空间。我已通过添加以下代码修复了该错误:

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

直接在可排序元素之后。

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>

在整个页面中查看此代码段(使用代码段右上方的链接)更为有用。