I'm having some problems while implementing jQue开发者_Python百科ry Draggable http://jqueryui.com/demos/draggable/ on Android. I've created the html code and tested it using my browser. Then I compiled it on build.phonegap.com. After getting the .apk I installed it on my xperia x8 which is using Android 2.2 Froyo. The application ran well, but when I dragged the object it won't move.. Is there something wrong with my method? Thanks
This code maps touchstart
, touchmove
and touchend
to their appropriate mouse events:
There is still a bug with touchstart
/ mousedown
, because the coordinates cannot be mapped directly.
My idea to fix this is to delay the mousedown
dispatch until a touchmove
occurs and then dispatch both mouse events with the coordinates of touchmove
.
var mouseEventTypes = {
touchstart : "mousedown",
touchmove : "mousemove",
touchend : "mouseup"
};
for (originalType in mouseEventTypes) {
document.addEventListener(originalType, function(originalEvent) {
event = document.createEvent("MouseEvents");
touch = originalEvent.changedTouches[0];
event.initMouseEvent(mouseEventTypes[originalEvent.type], true, true,
window, 0, touch.screenX, touch.screenY, touch.clientX,
touch.clientY, touch.ctrlKey, touch.altKey, touch.shiftKey,
touch.metaKey, 0, null);
originalEvent.target.dispatchEvent(event);
});
}
I use some script but forget where i take it:
*
* Copyright 2011, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Depends:
* jquery.ui.widget.js
* jquery.ui.mouse.js
*/
(function(b){b.support.touch="ontouchend" in document;if(!b.support.touch){return;}var c=b.ui.mouse.prototype,e=c._mouseInit,a;function d(g,h){if(g.originalEvent.touches.length>1){return;}g.preventDefault();var i=g.originalEvent.changedTouches[0],f=document.createEvent("MouseEvents");f.initMouseEvent(h,true,true,window,1,i.screenX,i.screenY,i.clientX,i.clientY,false,false,false,false,0,null);g.target.dispatchEvent(f);}c._touchStart=function(g){var f=this;if(a||!f._mouseCapture(g.originalEvent.changedTouches[0])){return;}a=true;f._touchMoved=false;d(g,"mouseover");d(g,"mousemove");d(g,"mousedown");};c._touchMove=function(f){if(!a){return;}this._touchMoved=true;d(f,"mousemove");};c._touchEnd=function(f){if(!a){return;}d(f,"mouseup");d(f,"mouseout");if(!this._touchMoved){d(f,"click");}a=false;};c._mouseInit=function(){var f=this;f.element.bind("touchstart",b.proxy(f,"_touchStart")).bind("touchmove",b.proxy(f,"_touchMove")).bind("touchend",b.proxy(f,"_touchEnd"));e.call(f);};})(jQuery);
It work perfect with jquery-ui. U just need to add it to your html code like js library
To make clicks also work...
var mouseEventTypes = {
touchstart : "mousedown",
touchmove : "mousemove",
touchend : "mouseup",
click : clickEvent
};
for(originalType in mouseEventTypes) {
document.addEventListener(originalType, function(originalEvent) {
if (originalEvent.type != 'click' && originalEvent.type != 'touchstart')
originalEvent.preventDefault();
event = document.createEvent("MouseEvents");
touch = originalEvent.changedTouches[0];
event.initMouseEvent(mouseEventTypes[originalEvent.type], true, true, window, 0, touch.screenX, touch.screenY, touch.clientX, touch.clientY, touch.ctrlKey, touch.altKey, touch.shiftKey, touch.metaKey, 0, null);
originalEvent.target.dispatchEvent(event);
event.preventDefault();
});
I used mixture of solutions above and realized that it helped with draggable elements, but it also made some elements in my project without ability to trigger click events on them, because the code above was preventing touchend events. I solved this problem. My version keeps draggable elements working and also keeps ability of other document elements to receive click events:
(function() {
function init() {
var mouseEventTypes = {
touchstart : "mousedown",
touchmove : "mousemove",
touchend : "mouseup"
};
for (originalType in mouseEventTypes) {
document.addEventListener(originalType, function(originalEvent) {
if(originalEvent.type == 'click')
return;
if (originalEvent.type != 'touchstart' && originalEvent.type !='touchend'){
originalEvent.preventDefault();
}
event = document.createEvent("MouseEvents");
touch = originalEvent.changedTouches[0];
event.initMouseEvent(mouseEventTypes[originalEvent.type], true, true, window, 0, touch.screenX, touch.screenY, touch.clientX, touch.clientY, touch.ctrlKey, touch.altKey, touch.shiftKey, touch.metaKey, 0, null);
originalEvent.target.dispatchEvent(event);
event.preventDefault();
});
}
}
init();
})();
Maybe it will help someone with similar issue. This problem with draggable elements occured only on my Galaxy Tab GT-P5110, Android version 4.0.4.
you can check out this question for a couple of suggestions and explanation of what is/isn't possible right now. It's my opinion that jQuery Mobile will probably have this as a possibility sooner or later.
As an extension to Nappy's answer:
I have tried his code snippet on an app I am building for Android devices. It compiles fine and I am able to drag (in my case, a square) around, however the touchmove mouse event type only fires for 2 seconds and then stops.
This gives the impression that the object is not draggable, however on release, the object is moved to that location.
To fix this a simple one line of code is needed within the event listener:
<script type="text/javascript" charset="utf-8">
// Wait for PhoneGap to load
//
document.addEventListener("deviceready", onDeviceReady, false);
// PhoneGap is ready
//
function onDeviceReady() {
$(".shape").draggable();
var mouseEventTypes = {
touchstart : "mousedown",
touchmove : "mousemove",
touchend : "mouseup"
};
for (originalType in mouseEventTypes) {
document.addEventListener(originalType, function(originalEvent) {
originalEvent.preventDefault();
event = document.createEvent("MouseEvents");
touch = originalEvent.changedTouches[0];
event.initMouseEvent(mouseEventTypes[originalEvent.type], true, true,
window, 0, touch.screenX, touch.screenY, touch.clientX,
touch.clientY, touch.ctrlKey, touch.altKey, touch.shiftKey,
touch.metaKey, 0, null);
originalEvent.target.dispatchEvent(event);
event.preventDefault();
});
}
}
</script>
The override of preventDefault fixes the issue with the mousedown handler not firing.
精彩评论