Javascript Drag and drop для сенсорных устройств [закрыто]

120

Я ищу плагин drag & DROP, который работает на сенсорных устройствах.

Я бы хотел, чтобы функциональность была аналогична плагину jQuery UI, который позволяет «отбрасывать» элементы.

Jqtouch плагин поддерживает перетаскивание, но не падая.

Вот перетаскивание, которое поддерживает только iPhone / iPad.

Может ли кто-нибудь указать мне на плагин перетаскивания, который работает на android / ios?

... Или можно обновить плагин jqtouch для возможности сбрасывания, он уже работает на Andriod и IOS.

Спасибо!

Джо
источник
1
Это в процессе, но я не знаю, какие устройства его поддерживают: Этот plugins.jquery.com/project/mobiledraganddrop ... вы просматривали библиотеки jQuerymobile.com? Я также нашел этот повторяющийся вопрос SO: stackoverflow.com/questions/3172100/…
iivel
Спасибо. Да, mobiledraganddrop поддерживает только щелчок и отпускание на мобильных устройствах. На jQuerymobile.com я ничего не нашел. Ответ на другой вопрос уже отмечен как правильный и относится к sencha.com/products/touch с ограниченной лицензией на исходный код.
joe
Мне любопытно тот, который работает в мобильных и настольных браузерах.
Lime

Ответы:

258

Вы можете использовать пользовательский интерфейс Jquery для перетаскивания с дополнительной библиотекой, которая переводит события мыши в касание, что вам нужно, библиотека, которую я рекомендую, - https://github.com/furf/jquery-ui-touch-punch , с это ваше перетаскивание из пользовательского интерфейса JQuery должно работать на сенсорных устройствах

или вы можете использовать этот код, который я использую, он также преобразует события мыши в сенсорные и работает как по волшебству.

function touchHandler(event) {
    var touch = event.changedTouches[0];

    var simulatedEvent = document.createEvent("MouseEvent");
        simulatedEvent.initMouseEvent({
        touchstart: "mousedown",
        touchmove: "mousemove",
        touchend: "mouseup"
    }[event.type], true, true, window, 1,
        touch.screenX, touch.screenY,
        touch.clientX, touch.clientY, false,
        false, false, false, 0, null);

    touch.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
}

function init() {
    document.addEventListener("touchstart", touchHandler, true);
    document.addEventListener("touchmove", touchHandler, true);
    document.addEventListener("touchend", touchHandler, true);
    document.addEventListener("touchcancel", touchHandler, true);
}

И в вашем document.ready просто вызовите функцию init ()

код найден здесь

ryuutatsuo
источник
11
Спасибо, на моем устройстве Android теперь можно перетаскивать. Однако событие click больше не запускается, когда я нажимаю на него. Есть идеи, как это исправить?
Джон Ландхир
9
Примечание. Поскольку прослушиватель событий зарегистрирован для всего документа, это решение также отключает прокрутку на моем Nexus S ...
Итан Лерой,
29
Спасибо, что поделились этим. Тем не менее, вы должны отдать должное первоначальному автору опубликованного вами кода. ross.posterous.com/2008/08/19/iphone-touch-events-in-javascript
undefined
2
@JohnLandheer Я исправил проблему, прикрепив прослушиватели событий только к объектам, которые я хотел перетащить,document.getElementById('draggableContainer').addEventListener(...
chiliNUT
1
Touch-punch - это здорово. Один из тех, что «просто работает». Увы, он не поддерживает двойное касание ... что очень хотелось бы увидеть.
Д.А.
21

Для тех, кто хочет использовать это и сохранить функциональность щелчка (как упоминает Джон Ландхир в своем комментарии), вы можете сделать это всего с парой модификаций:

Добавьте пару глобалов:

var clickms = 100;
var lastTouchDown = -1;

Затем измените оператор switch с оригинала на это:

var d = new Date();
switch(event.type)
{
    case "touchstart": type = "mousedown"; lastTouchDown = d.getTime(); break;
    case "touchmove": type="mousemove"; lastTouchDown = -1; break;        
    case "touchend": if(lastTouchDown > -1 && (d.getTime() - lastTouchDown) < clickms){lastTouchDown = -1; type="click"; break;} type="mouseup"; break;
    default: return;
}

Вы можете настроить "клики" по своему вкусу. По сути, это просто наблюдение за «сенсорным запуском», за которым быстро следует «касание» для имитации щелчка.

EZ Hart
источник
@EZ Hart - не могли бы вы сообщить мне, где разместить свой код в приведенном выше коде, чтобы включить событие щелчка ???
Валай
1
@ChakoDesai - Код в ответе был сильно отредактирован с тех пор, как я написал свой ответ. Посетите stackoverflow.com/posts/6362527/revisions и посмотрите код от 30 июня 2011 г .; мой ответ будет иметь больше смысла на основе этой версии.
EZ Hart
@EZ Hart - Я обновил свой код по указанному URL. Но почему иногда clickработает, а иногда нет ???
Валай
@ChakoDesai - Я не могу быть уверенным, не видя вашего кода. Вы можете задать для этого новый вопрос.
EZ Hart
Обновленный ответ, чтобы заставить вышеуказанный код работать с событиями щелчка, можно найти здесь: stackoverflow.com/questions/28218888/…
Blunderfest
12

Спасибо за приведенные выше коды! - Я попробовал несколько вариантов, и это был билет. У меня были проблемы с тем, что preventDefault предотвращал прокрутку на ipad - сейчас я тестирую перетаскиваемые элементы, и пока он отлично работает.

if (event.target.id == 'draggable_item' ) {
    event.preventDefault();
}
gregpress
источник
Вы тестировали это в Windows Phone? Или что-нибудь кроме iPhone? Исходя из прошлого опыта, кажется, что это идеально работает на iPhone / iPad, но не работает на других устройствах, особенно на телефонах Windows.
почти новичок
10

У меня было то же решение, что и у gregpress answer , но мои перетаскиваемые элементы использовали класс вместо идентификатора. Вроде работает.

var $target = $(event.target);  
if( $target.hasClass('draggable') ) {  
    event.preventDefault();  
}
Эрик
источник
4
Тот факт, что вы просто использовали другой селектор, не требует отдельного ответа, но вместо этого вы должны были прокомментировать ответ @ gregpress.
bPratik
2
@bPratik, если только он не хотел, чтобы ответ был более красивым, и тот факт, что он предоставил полный пример кода, действительно требует отдельного ответа. Хотя следовало оставить комментарий со ссылкой на его ответ ...
drzaus 03
8

Старый нить знаю .......

Проблема с ответом @ryuutatsuo заключается в том, что он также блокирует любой ввод или другой элемент, который должен реагировать на «щелчки» (например, вводы), поэтому я написал это решение. Это решение позволило использовать любую существующую библиотеку перетаскивания, основанную на событиях mousedown, mousemove и mouseup на любом сенсорном устройстве (или компьютере). Это тоже кроссбраузерное решение.

Я тестировал на нескольких устройствах, и он работает быстро (в сочетании с функцией перетаскивания в ThreeDubMedia (см. Также http://threedubmedia.com/code/event/drag )). Это решение jQuery, поэтому вы можете использовать его только с библиотеками jQuery. Я использовал для этого jQuery 1.5.1, потому что некоторые новые функции не работают должным образом с IE9 и выше (не тестировались с более новыми версиями jQuery).

Прежде чем добавлять к событию операцию перетаскивания или перетаскивания, необходимо сначала вызвать эту функцию :

simulateTouchEvents(<object>);

Вы также можете заблокировать все компоненты / дочерние элементы для ввода или для ускорения обработки событий, используя следующий синтаксис:

simulateTouchEvents(<object>, true); // ignore events on childs

Вот код, который я написал. Я использовал несколько хороших приемов, чтобы ускорить оценку вещей (см. Код).

function simulateTouchEvents(oo,bIgnoreChilds)
{
 if( !$(oo)[0] )
  { return false; }

 if( !window.__touchTypes )
 {
   window.__touchTypes  = {touchstart:'mousedown',touchmove:'mousemove',touchend:'mouseup'};
   window.__touchInputs = {INPUT:1,TEXTAREA:1,SELECT:1,OPTION:1,'input':1,'textarea':1,'select':1,'option':1};
 }

$(oo).bind('touchstart touchmove touchend', function(ev)
{
    var bSame = (ev.target == this);
    if( bIgnoreChilds && !bSame )
     { return; }

    var b = (!bSame && ev.target.__ajqmeclk), // Get if object is already tested or input type
        e = ev.originalEvent;
    if( b === true || !e.touches || e.touches.length > 1 || !window.__touchTypes[e.type]  )
     { return; } //allow multi-touch gestures to work

    var oEv = ( !bSame && typeof b != 'boolean')?$(ev.target).data('events'):false,
        b = (!bSame)?(ev.target.__ajqmeclk = oEv?(oEv['click'] || oEv['mousedown'] || oEv['mouseup'] || oEv['mousemove']):false ):false;

    if( b || window.__touchInputs[ev.target.tagName] )
     { return; } //allow default clicks to work (and on inputs)

    // https://developer.mozilla.org/en/DOM/event.initMouseEvent for API
    var touch = e.changedTouches[0], newEvent = document.createEvent("MouseEvent");
    newEvent.initMouseEvent(window.__touchTypes[e.type], true, true, window, 1,
            touch.screenX, touch.screenY,
            touch.clientX, touch.clientY, false,
            false, false, false, 0, null);

    touch.target.dispatchEvent(newEvent);
    e.preventDefault();
    ev.stopImmediatePropagation();
    ev.stopPropagation();
    ev.preventDefault();
});
 return true;
}; 

Что он делает: сначала он переводит события одиночного касания в события мыши. Он проверяет, вызвано ли событие элементом на / в элементе, который нужно перетаскивать. Если это элемент ввода, такой как input, textarea и т. Д., Он пропускает перевод, или если к нему прикреплено стандартное событие мыши, оно также пропускает перевод.

Результат: все элементы перетаскиваемого элемента по-прежнему работают.

Удачного кодирования, приветц, Эрвин Хантьес

Codebeat
источник
какой объект мне передать simulateTouchEvents(<object>, true);???
Валай
Например: simulateTouchEvents ($ ('# yourid;), true); или simulateTouchEvents (document.getElementById ('yourid'), true); и т. д.
Codebeat
не могли бы вы взглянуть на мою ссылку с другим вопросом ???
Валай
Используйте treedubmedia.com/code/event/drag и отключите перемещение элемента по оси x или y. Используя код из этой статьи, вы можете «прокручивать» полосы прокрутки. Но знайте, почему вы хотите это сделать, потому что на странице на мобильном телефоне уже есть полосы прокрутки. Не понимаю, что ты хочешь с этим делать. Успех!
Codebeat
Я должен добавить перетаскивание столбцов и прокрутку обоих. Когда я включаю touchсобытия chrome, я не могу прокручивать таблицу. Даже на мобильном телефоне.
Валай