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

114

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

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

плагин jqtouch поддерживает перетаскивание, но не отбрасывает.

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

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

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

Спасибо!

  • 1
    Это выполняется, но я не знаю, какие устройства его поддерживают: Этот plugins.jquery.com/project/mobiledraganddrop ... Вы просматривали библиотеки jQuerymobile.com? Я также нашел этот дублирующий вопрос SO: stackoverflow.com/questions/3172100/…
  • 0
    Благодарю. Да, mobiledraganddrop поддерживает только перетаскивание на мобильных устройствах. Я не смог найти ничего на jQuerymobile.com. Другой вопрос имеет ответ, уже помеченный как правильный, который относится к sencha.com/products/touch, который имеет ограниченную исходную лицензию.
Показать ещё 1 комментарий
Теги:
touch

5 ответов

251
Лучший ответ

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

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

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);
}

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

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

  • 0
    Потрясающие! Единственное, что с jquery mobile, вы захотите привязать к .live ("pagecreate") поверх document.ready.
  • 10
    Спасибо, на моем Android-устройстве все теперь перетаскивается. Однако событие click больше не срабатывает, когда я нажимаю на него. Есть идеи как это исправить?
Показать ещё 17 комментариев
20

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

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

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;
}

Вы можете настроить "клики" на свой вкус. В основном это просто наблюдение за "touchstart", за которым быстро последовал "touchhend", чтобы имитировать щелчок.

  • 0
    @EZ Харт - не могли бы вы, пожалуйста, дать мне знать, куда поместить ваш код в приведенном выше коде, чтобы включить событие клика ???
  • 1
    @ChakoDesai - Код в ответе был отредактирован с тех пор, как я написал свой ответ. Посетите stackoverflow.com/posts/6362527/revisions и посмотрите на код от 30 июня 2011 года; мой ответ будет иметь больше смысла, основываясь на этой версии.
Показать ещё 3 комментария
12

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

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

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

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

Старый поток, который я знаю.......

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

Я тестировал несколько устройств и работает быстро (в сочетании с функцией перетаскивания ThreeDubMedia (см. также http://threedubmedia.com/code/event/drag)). Это решение jQuery, поэтому вы можете использовать его только с jQuery libs. Я использовал 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 и т.д., Он пропускает перевод, или если к нему прикреплено стандартное событие мыши, оно также пропустит перевод.

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

Счастливое кодирование, greetz, Эрвин Хаантес

  • 0
    какой объект я должен передать в simulateTouchEvents(<object>, true); ???
  • 0
    Например: simulateTouchEvents ($ ('# yourid;), true); или simulateTouchEvents (document.getElementById ('yourid'), true); так далее
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню