Передача/изменение события jQuery UI drag

Я хочу, чтобы пользователи могли перетаскивать горизонтальную панель меню влево и вправо. Я понимаю, что есть много библиотек карусели и слайдера, которые имеют такое поведение, но ни одна из них не соответствует ситуации.

Когда пользователь перетаскивает LI, он может передать новую информацию о смещении x в левое поле первого LI?

Я взял у него удар: http://jsfiddle.net/n92ng9uz/

Основная проблема с вышеприведенной скриптой заключается в том, что смещение все еще применяется к индивидуальному LI, и если я не предотвращу пузырь, событие перетаскивания перестает быть гладким.

Спасибо за помощь/руководство!

Ответ 1

Так как вы указали в комментариях, что для использования margin-left в первом элементе li необходимо использовать и не изменять позицию ul, я уверен, что это нелегко сделать, используя jQuery UI перетаскивается. Если бы мы перетащили li, мы бы не ловили события мыши на других li s, и если бы мы могли перетащить ul, мы не могли бы легко повлиять только на margin-left первого li, а не положение ul.

Ниже приведено live demo решение, которое напрямую использует события мыши вместо использования jQuery UI:

var firstLI = $('li:first-child');

var initx = 0;
var dragstartx = 0;
var dragging = false;

$("ul").mousedown(function(e) {
    dragging = true;
    dragstartx = e.pageX;
    initx = parseInt(firstLI.css("marginLeft"), 10);
});

$("ul").mousemove(function(e) {
    if (dragging) {
        firstLI.css("marginLeft", (initx + e.pageX - dragstartx) + "px");
    }
});

$("ul").mouseleave(function(e) {
    dragging = false;
});

$("ul").mouseup(function(e) {
    dragging = false;
});
ul {
    list-style: none;
    margin: 0;
    padding: 0;
    overflow: hidden;
    white-space: nowrap;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

ul > li {
    display: inline-block;
    padding: 10px;
}

ul > li:nth-child(odd) {
    background: orangered;
}

ul > li:nth-child(even) {
    background: gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
    <li>Link 1</li>
    <li>Link 2</li>
    <li>Link 3</li>
    <li>Link 4</li>
    <li>Link 5</li>
    <li>Link 6</li>
    <li>Link 7</li>
    <li>Link 8</li>
    <li>Link 9</li>
    <li>Link 10</li>
</ul>

Ответ 2

РЕДАКТИРОВАТЬ: Nevermind... понял это... Вам нужно переместить каждый элемент слева от разности позиций. Я думаю, что это то, что вам нужно: http://jsfiddle.net/xwesf1Lt/. Скажи мне, если я ошибаюсь. Обратите внимание, что я изменил переменную diff на левую позицию.

Кроме того, вместо изменения поля мы изменяем левый атрибут.

var firstLI = $('ul:first-child')[0];
firstLI.style.marginLeft = 0;

$('li').draggable({
    axis: 'x',
    drag: function(e, ui) {
        var diff = ui.position.left;
        console.log(diff);
        var currentLeft = parseInt(firstLI.style.marginLeft, 10);
        var offset = currentLeft + diff + 'px';
        //firstLI.style.marginLeft = diff;
        //  to drag all of them:

        $("li").each(function(index) {
            $(this).css("left", offset);
        });

        // with this enabled, can only be moved 1px at a time..?
        // e.preventDefault();
    }
});

Ответ 3

Не будет ли это работать? Добавление поля к ul? Кажется, работает на скрипке!

var ul = $('ul');

ul.draggable({
    axis: 'x',
    drag: function(e, ui) {
        ul.css({marginLeft: ui.position - ui.originalPosition});
    }
});

Ответ 4

Если вы хотите, чтобы пользователи имели возможность свободно перетаскивать навигационную панель, а затем она должна отбрасываться в одном месте, тогда вы можете попробовать подключить плагин jquery dad. Это, безусловно, лучший плагин перетаскивания, который я использовал, для упрощения кода.

Нажмите здесь, чтобы увидеть его демонстрацию и документацию, если хотите.