JQuery Перетаскивание на сенсорных устройствах (iPad, Android)

У нас есть карточный игровой сайт, в котором широко используется jQuery Draggable & Droppable и который почти безупречно работает (при использовании мыши) почти год.

Мы бы ДЕЙСТВИТЕЛЬНО хотели, чтобы сайт работал на устройствах с сенсорным экраном, но мы не можем заставить jQuery перетащить и особенно отказаться от функциональности, чтобы работать надежно.

Перетаскивание работает «ok», если только div не перетаскивается внутри другого элемента dom с любым видом смещения, поля, отступов и т. Д. Если это так, перемещенный элемент также смещается от пальца пользователя на аналогичную сумму. Может показаться неважным, но это делает интерфейс непривлекательным.

Сбрасывание просто не работает.

Мы исследовали различные варианты, представленные здесь на SO (попробуем обновить этот пост со ссылками на некоторые из них, если можно), но никто не работает для нас.

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

Большинство сообщений SO и Google по этой теме, похоже, заканчиваются в конце 2010 года, что заставляет меня думать, что есть очевидный ответ, что, может быть, мы просто пропали без вести.

BTW, функциональность, которую мы ищем, явно технически возможна, потому что библиотеки YUI для перетаскивания работают так, как ожидалось. К сожалению, мы не можем оптимизировать рефакторинг сайта для перехода с jQuery на YUI.

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

Благодаря!

Solutions Collecting From Web of "JQuery Перетаскивание на сенсорных устройствах (iPad, Android)"

Вставьте это в начало вашего .js-файла:

(function ($) { // Detect touch support $.support.touch = 'ontouchend' in document; // Ignore browsers without touch support if (!$.support.touch) { return; } var mouseProto = $.ui.mouse.prototype, _mouseInit = mouseProto._mouseInit, touchHandled; function simulateMouseEvent (event, simulatedType) { //use this function to simulate mouse event // Ignore multi-touch events if (event.originalEvent.touches.length > 1) { return; } event.preventDefault(); //use this to prevent scrolling during ui use var touch = event.originalEvent.changedTouches[0], simulatedEvent = document.createEvent('MouseEvents'); // Initialize the simulated mouse event using the touch event's coordinates simulatedEvent.initMouseEvent( simulatedType, // type true, // bubbles true, // cancelable window, // view 1, // detail touch.screenX, // screenX touch.screenY, // screenY touch.clientX, // clientX touch.clientY, // clientY false, // ctrlKey false, // altKey false, // shiftKey false, // metaKey 0, // button null // relatedTarget ); // Dispatch the simulated event to the target element event.target.dispatchEvent(simulatedEvent); } mouseProto._touchStart = function (event) { var self = this; // Ignore the event if another widget is already being handled if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) { return; } // Set the flag to prevent other widgets from inheriting the touch event touchHandled = true; // Track movement to determine if interaction was a click self._touchMoved = false; // Simulate the mouseover event simulateMouseEvent(event, 'mouseover'); // Simulate the mousemove event simulateMouseEvent(event, 'mousemove'); // Simulate the mousedown event simulateMouseEvent(event, 'mousedown'); }; mouseProto._touchMove = function (event) { // Ignore event if not handled if (!touchHandled) { return; } // Interaction was not a click this._touchMoved = true; // Simulate the mousemove event simulateMouseEvent(event, 'mousemove'); }; mouseProto._touchEnd = function (event) { // Ignore event if not handled if (!touchHandled) { return; } // Simulate the mouseup event simulateMouseEvent(event, 'mouseup'); // Simulate the mouseout event simulateMouseEvent(event, 'mouseout'); // If the touch interaction did not move, it should trigger a click if (!this._touchMoved) { // Simulate the click event simulateMouseEvent(event, 'click'); } // Unset the flag to allow other widgets to inherit the touch event touchHandled = false; }; mouseProto._mouseInit = function () { var self = this; // Delegate the touch handlers to the widget's element self.element .on('touchstart', $.proxy(self, '_touchStart')) .on('touchmove', $.proxy(self, '_touchMove')) .on('touchend', $.proxy(self, '_touchEnd')); // Call the original $.ui.mouse init method _mouseInit.call(self); }; })(jQuery); 

Позвони мне по утрам;) (это действительно самонадеянно, я не писал этого решения, хотя я бы хотел, чтобы у меня было, я бы это сделал, если бы вспомнил, где я его нашел, если кто-нибудь знает, откуда этот код пришел, прокомментируй и Кредит этому лицу)

UPDATE: Здесь вы идете: вот где я нашел это

Я предлагаю jQuery UI Touch Punch . Я тестировал его на iOS 5 и Android 2.3, и он отлично работает на обоих.

Старая нить я знаю …….

Проблема с ответом @likwid_t заключается в том, что он блокирует и любой вход или другой элемент, который должен реагировать на «клики» (например, входы), поэтому я написал это решение. Это решение позволило использовать любую существующую библиотеку перетаскивания, которая основана на событиях 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, Erwin Haantjes

Я создал плагин jQuery на основе ответа Erwinus: https://github.com/RushPL/jquery.touch-mouse

Вы можете попробовать этот плагин, но, похоже, работают на iphone, ipod и ipad. Не уверен, решает ли вы проблему. Может быть конкретным …

http://code.google.com/p/jquery-ui-for-ipad-and-iphone/

Но андроид все еще ищет решение.

Дайте мне знать, если это поможет. С уважением Рикардо Родригес

У LikWidT есть простейшее решение, поданное с сайта, на который делается ссылка. Было бы здорово, если бы какой-либо из программистов JQuery UI мог добавить этот код или аналогичный их пакет. JQuery – это, безусловно, самый простой пакет для создания контента перетаскивания для веб-разработчиков … это, к сожалению, главный недостаток почти всех устройств, имеющих сенсорные экраны в настоящее время. Теперь я кодирую Surface Pro, что открывает глаза на эти проблемы лично.

Просто повторите ссылку на сайт: https://github.com/furf/jquery-ui-touch-punch

Изменить: Также выяснить, насколько просто это исправление. Я должен был сначала гарантировать, что я повторно заказал свои включенные файлы, чтобы JQuery Javascript-файл был сначала Jquery UI Javascript, а затем мои файлы CSS. Затем я просто копирую / вставляю ниже включенных файлов код Javascript в сообщение выше, и это все. Я не модифицировал код, это просто функция, которая ищет любые касания в реальном времени и преобразует их в эквивалентные действия мыши. Отсюда и мои предыдущие утверждения для JQuery-кодеров.

Учитывая, что работал на меня:

 eventAfterRender: function (event, element, view ) { element.draggable(); }, 

Протестировано на HTC One M8 под Android 6.13 / Samsung Galaxy Tab S2

 function simulateMouseEvent (event, simulatedType) { //use this function to simulate mouse event // restriction to preserve input use window.__touchInputs = {INPUT:1,TEXTAREA:1,SELECT:1,OPTION:1,'input':1,'textarea':1,'select':1,'option':1}; if( window.__touchInputs[event.target.tagName] ) return ; }