Перетаскивание мышью в пользовательском интерфейсе jQuery - PullRequest
3 голосов
/ 05 июня 2009

Используя jQuery 1.2.x и jQuery UI 1.5.x, можно было инициировать перетаскивание вручную следующим образом:

jQuery("#myDiv").mousedown(function(ev) {
target = jQuery(ev.target);
if (target.hasClass("drag-me")) {
    target.draggable({
        helper: "clone",
        start: function()
        {
            console.log("drag start");
        },
        stop: function()
        {
            jQuery(this).draggable("destroy");
        }
    }).trigger("mousedown.draggable", [ev]);
} });

Применяется к следующему HTML:

<div id="myDiv">
<div class="drag-me"></div>
<div class="drag-me"></div>
<div class="drag-me"></div>
<div class="drag-me"></div>
<div class="drag-me"></div>
<div class="drag-me"></div>
<div class="drag-me"></div>
</div>

Это был удобный способ применить перетаскивание к элементам внутри контейнера, чьи дочерние элементы динамически изменялись. Мне нравится называть это «делегированием перетаскивания».

Однако с выпуском jQuery 1.3.x & jQuery 1.6+ вышеприведенный скрипт перестал работать. Использование jQuery 1.3.2 и jQuery UI 1.7.1 возвращает ошибку «слишком много рекурсии».

Как я могу активировать перетаскивание вручную? Есть предложения?

Ответы [ 5 ]

12 голосов
/ 23 мая 2011

Ответы выше кажутся слишком сложными.

$('.nonDraggableObjectWhichTriggersDrag').mousedown(function(e) {
   $('.draggableObject').trigger(e);
});
3 голосов
/ 15 марта 2010

Оказывается, все гораздо проще, чем вы ожидаете. Глядя на документацию метода .trigger (), не упоминается тот факт, что в качестве аргумента можно также указать исходное событие, а не просто строковое представление типа события.

Таким образом, можно добиться более эффективного делегированного перетаскивания, например:

$("ul#dynamiclist").delegate("li", "mousedown", function(event) {
    $(this).draggable({
            helper: "clone",
            cursorAt: { left: 5, top: -5 },
            cursor: "move",
            stop: function() {
                    $(this).draggable("destroy");
            }
    }); });

Идеальным решением было бы наличие в библиотеке пользовательского интерфейса какого-либо метода для выполнения такого типа делегирования изначально для динамических элементов ....

Обратите внимание, что это применимо к jQuery 1.4.2 и jQuery UI 1.7.2

3 голосов
/ 01 июля 2010

В случае, если вы не используете jQuery 1.4 (и, следовательно, у вас нет метода делегата ()), есть другое решение.

Чтобы остановить рекурсию, нужно вызвать stopPropagate () для событий mousedown для всех элементов:

$('drag-me').mousedown(function(ev){
  ev.stopPropagation();
});

Также измените свой код следующим образом (обратите внимание на вызов stopPropagation () внизу):

jQuery("#myDiv").mousedown(function(ev) {
target = jQuery(ev.target);
if (target.hasClass("drag-me")) {
        target.draggable({
                helper: "clone",
                start: function()
                {
                        console.log("drag start");
                },
                stop: function()
                {
                        jQuery(this).draggable("destroy");
                }
        }).trigger("mousedown.draggable", [ev]);
        ev.stopPropagation()
    }
});

Это должно исправить вашу бесконечную рекурсию. (по крайней мере, для меня это произошло в аналогичной ситуации)

1 голос
/ 09 июня 2009

Если бы вы могли опубликовать весь пример кода (с html и соответствующими тегами сценария с нерабочими версиями), я мог бы помочь, вероятно, указать, что не так, и / или проверить проблему ....

Однако я не уверен, что вы хотите передать массив из 1 объекта [ev] в качестве второго параметра для вызова триггера.

Документация гласит: "Наконец, вы можете передать буквальный объект с данными. Он будет скопирован в реальный объект jQuery.Event. Обратите внимание, что в этом случае вы должны указать атрибут типа."

Можете ли вы проверить, что это (должно | работать раньше), как вы написали, и / или, возможно, вставить еще какой-нибудь код или URL на соответствующую страницу? Я был бы рад еще раз взглянуть на это.

Надеюсь, это поможет. :)

Редактировать: Снова взглянуть на это. Он делает именно то, что вы просите. На событии mousedown вы делаете некоторые вещи, а затем завершаете, вызывая другое событие mousedown, которое будет выполнять некоторые действия, а затем вызывать другое событие нажатия мыши и так далее ... и так далее ...

Вы создали бесконечный цикл.

Почему бы просто не сделать так, чтобы релевантные элементы div перетаскивались при загрузке страницы, а не при первом нажатии? Разве это не позволило бы избежать этой проблемы?

Также взгляните на этот пост , и мне было бы очень интересно увидеть какой-нибудь код, который раньше работал. Как написано, я не уверен, что понимаю последовательность того, как код будет эмулировать полное событие «перетаскивания» - состоящее из событий mousedown, mousemove и mouse up. Дай мне знать. Спасибо!

0 голосов
/ 01 февраля 2015

другие ответы у меня не сработали, я использовал плагин jquery ui simulate

https://github.com/jquery/jquery-ui/blob/9e8e339648901899827a58e5bf919f7dda03b88e/tests/jquery.simulate.js

$("#myElement").simulate('drag');
...