jQuery拖放触摸设备(iPad,Android)

我们有一个纸牌游戏网站,广泛使用jQuery Draggable&Droppable,几乎完美的工作(当使用鼠标)近一年。

我们真的想让网站在触摸屏设备上工作,但我们似乎无法得到jQuery的拖动,特别是拖放function,以可靠地工作。

拖动工程“确定”,除非被拖动的div在另一个dom元素中,并且具有任何types的偏移量,边距,填充等。如果是,则拖动的元素也从用户的手指偏移相似的量。 可能听起来不是什么大不了的事情,但它使界面变得不可用。

丢弃似乎不起作用。

我们已经研究了这里介绍的各种选项(如果可以的话,会尝试更新这个post的链接),但是没有一个适合我们。

我们也研究过jQuery Mobile,但这仍然是alpha,甚至似乎更像是一个使网站模拟手机UI与我们正在寻找的框架的框架。

大多数关于这个话题的SO和Google的post似乎都在2010年末的时候发生了,这让我觉得有一个明显的答案,也许我们只是错过了。

顺便说一句,我们正在寻找的function在技术上显然是可能的,因为用于拖放的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); 

(早上打电话给我)(这真的很傲慢,我没有写这个解决scheme,虽然我希望我有,如果我记得我find它的地方,我会参考它,如果有人知道这个代码来自哪里,请评论和信用那个人)

更新:你在这里: 这是我find这个

我build议jQuery UI触摸打孔 。 我已经在iOS 5和Android 2.3上进行了testing,并且在两者上都很好。

我知道老线程…….

问题与@likwid_t的答案是,它也阻止任何input或其他元素,必须对“点击”(例如input)作出反应,所以我写了这个解决scheme。 这个解决scheme可以使用任何现有的基于鼠标,鼠标移动和鼠标事件的拖放库在任何触摸设备(或cumputer)上。 这也是一个跨浏览器的解决scheme。

我已经在几个设备上进行了testing,它的工作速度很快(结合ThreeDubMedia的拖放function(另请参阅http://threedubmedia.com/code/event/drag ))。 这是一个jQuery解决scheme,所以你只能用jQuery库。 我已经使用jQuery 1.5.1 ,因为一些新的function不能正常使用IE9及以上版本(未使用新版本的jQuery进行testing)。

将任何拖放操作添加到事件之前,必须先调用此函数

 simulateTouchEvents(<object>); 

您还可以使用以下语法阻止所有组件/子项的input或加速事件处理:

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

function:首先,它将单点触摸事件转换为鼠标事件。 它检查一个事件是否是由必须被拖动的元素上的一个元素引起的。 如果是input,textarea等input元素,则跳过翻译,或者如果标准的鼠标事件连接到它,它也会跳过翻译。

结果:可拖动元素上的每个元素仍然在工作。

快乐的编码,问候,Erwin Haantjes

我创build了一个基于Erwinus的答案的jQuery插件: https : //github.com/RushPL/jquery.touch-mouse

你可以试试这个插件,但似乎适用于iphone,ipod和ipad。 不知道如果解决你的问题。 可以是一个具体的…

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

但Android仍在寻找解决scheme。

让我知道是否有帮助。 问候李嘉图罗德里格斯

LikWidT提供了最简单的解决scheme。 如果任何JQuery UI程序员可以将这些代码或类似的代码添加到他们的包中,那将是非常棒的。 Jquery无疑是最简单的为Web开发人员构build拖放内容的软件包…这不幸是现今几乎所有设备都具有触摸屏的主要缺陷。 我现在正在编写一个Surface Pro,用于亲自处理这些问题。

只需再次引用该网站: https : //github.com/furf/jquery-ui-touch-punch

编辑:也澄清这个修复程序是多么简单。 我不得不首先确保我重新命令我的包含文件,这样的JQuery的JavaScript文件是第一次然后JQuery的UI的Javascript然后我的CSS文件。 然后,我只是复制/粘贴在包含文件的Javascript代码在上面的post,就是这样。 我没有修改代码,它只是一个实时查找任何触摸的函数,并将它们转换为等效的鼠标操作。 因此,我上面的JQuery编码器断言。

鉴于为我工作:

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

在Android 6.13 /三星Galaxy Tab S2上testingHTC One M8

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