Как использовать jQuery UI Sortable для правильного пересечения? - PullRequest
0 голосов
/ 17 января 2019

Вот моя попытка анимирования 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 голосов
/ 22 января 2019

Вы видите ошибка # 8342

Сортируемый: Неверное поведение (или неверная документация) сортируемой опции tolerance: 'intersect'

Я тестировал обходные пути (с этот ответ (я исправил его для вертикального использования) и с этот ответ ) которые были связаны в комментарии Munim Munna, и оба обходных пути не работают правильно (очень очень глючно).

Обходной путь с tolerance: 'pointer'

Вы должны установить tolerance: 'pointer' вместе с cursorAt: {top: height/2, left: width/2} (половина размера от ширины и высоты вашего перетаскиваемого элемента).

Опция

tolerance : 'pointer' позволяет элементу заменить целевой элемент сразу же, как только курсор войдет в целевой элемент. По умолчанию было установлено значение tolerance : 'intersect', что означает, что элемент перекрывает другой элемент как минимум на 50%. Но, к сожалению, есть ошибка для этой опции (см. Верх моего ответа).

Попробуйте также использовать его с параметром cursorAt и без него или изменить значение. Эта опция перемещает сортировочный элемент или помощник, так что курсор всегда отображается для перетаскивания из одной и той же позиции Координаты могут быть заданы в виде хэша с использованием комбинации одной или двух клавиш: {top, left, right, bottom}.

Вот документация для tolerance опция и для cursorAt опция .

Обновление от 29.01.2019

Я исправил некоторые ошибки из 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>

Полезнее видеть этот фрагмент кода на полной странице (воспользуйтесь ссылкой справа вверху от фрагмента).

...