Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#14926 closed bug (duplicate)

ui.mouse support for touch events

Reported by: gvanmat Owned by:
Priority: minor Milestone: none
Component: ui.mouse Version: 1.12.0-beta.1
Keywords: Cc:
Blocked by: Blocking:

Description

The ui.mouse headless component is used by a number of other component features (draggable.js, sortable.js, resizable.js). This component only distributes mouse events. This falls short when used in a hybrid app.

The proposal is to utilize touch events when the browser supports them instead of mouse events. To minimize change, the touch events are normalized as native mouse events. The last touch point is pulled up to a corresponding simulated mouse event. The native simulated event is wrapped in a jquery event object. The simulated mouse events are passed to the placeholder methods but the native event is not dispatched.

Consider the following mapping: {'touchstart': 'mousedown', 'touchmove': 'mousemove', 'touchend': 'mouseup'}

Change History (4)

comment:1 Changed 4 years ago by gvanmat

Created pull request with the proposed fix: https://github.com/gvanmat/jquery-ui/pull/1

comment:2 Changed 4 years ago by gvanmat

Closed the last pull as it didn't pass lint or qunit tests. Please consider the following pull request: https://github.com/gvanmat/jquery-ui/pull/2

comment:3 Changed 4 years ago by Scott González

Resolution: duplicate
Status: newclosed

Duplicate of #4143.

comment:4 Changed 4 years ago by gvanmat

I used the following duck punch workaround:

var _mouseProto = $.uimouse?.prototype ? $.uimouse?.prototype : {}.prototype; var _mouseInit = _mouseProto_mouseInit?; var _mouseDestroy = _mouseProto_mouseDestroy?;

function _wrapTouch(event) {

if (["touchstart", "touchmove", "touchend", "touchcancel"].indexOf(eventtype?) === -1) {

return event;

}

var _getFirstTouchPoint = function(evt) {

if (evtchangedTouches? && evtchangedTouches?.length) {

return evtchangedTouches?[0];

} else if (evttargetTouches? && evttargetTouches?.length) {

return evttargetTouches?[0];

} else if (evttouches? && evttouches?.length) {

return evttouches?[0];

} return null;

};

var _TOUCH_TO_MOUSE_XREF = {"touchstart": "mousedown", "touchmove": "mousemove", "touchend": "mouseup", "touchcancel": "mouseup"}; var _COPY_SAFE_EVENT_PROPERTIES = {"altKey": true, "bubbles": true, "cancelable": true, "ctrlKey": true,

"currentTarget": true, "eventPhase": true, "metaKey": true, "target": true, "relatedTarget": true, "shiftKey": true, "timeStamp": true, "view": true, "which": true, "button": true, "buttons": true, "clientX": true, "clientY": true, "offsetX": true, "offsetY": true, "pageX": true, "pageY": true, "screenX": true, "screenY": true, "toElement": true, "char": true, "charCode": true, "key": true, "keyCode": true};

var simulatedEvent = document.createEvent("MouseEvent"); var touch = _getFirstTouchPoint(eventoriginalEvent?); simulatedEvent.initMouseEvent(_TOUCH_TO_MOUSE_XREF[ eventtype? ], true, true, window, 1,

touchscreenX?, touchscreenY?, touchclientX?, touchclientY?, false, false, false, false, 0, null);

Capture all interesting event properties. Similar to jQuery.event.fix. var props = {}; if (Object.defineProperty) {

var descriptor = {"value": touchtarget?, "writable": false, "enumerable": true, "configurable": false}; Object.defineProperty(simulatedEvent, "target", descriptor);

}

for (var key in simulatedEvent) {

if (_COPY_SAFE_EVENT_PROPERTIES[ key ] && !$.isFunction(simulatedEvent[ key ])) {

props[ key ] = simulatedEvent[ key ];

}

} if (!propstarget?)

propstarget? = touchtarget?;

Wrap a native simulated event in a jQuery.Event extending propertiea var dragEvent = $.Event(simulatedEvent, props); return dragEvent;

};

_mouseProto._touchStartDelegate = function(event) {

if (this_mouseDown?(_wrapTouch(event))) {

this._on(this.document, {"touchmove": this._touchMoveDelegate}); this._on(this.document, {"touchend": this._touchEndDelegate, "touchcancel": this._touchEndDelegate});

}

};

_mouseProto._touchMoveDelegate = function(event) {

var e = _wrapTouch(event); if (this_mouseCapture?(e)) {

event.preventDefault(); prevent browser scroll this_mouseMove?(_wrapTouch(e));

}

};

_mouseProto._touchEndDelegate = function(event) {

this._off(this.document, "touchmove touchend touchcancel"); this_mouseUp?(_wrapTouch(event));

};

_mouseProto_mouseInit? = function() {

this._on(this.element, {"touchstart": this._touchStartDelegate}); _mouseInit.call(this);

};

_mouseProto_mouseDestroy? = function() {

this._off(this.element, "touchstart"); this._off(this.document, "touchmove touchend touchcancel"); _mouseDestroy.call(this);

};

Version 0, edited 4 years ago by gvanmat (next)
Note: See TracTickets for help on using tickets.