SAPUI5 event delegation automatically handles both mouse and touch events simultaneously. If you are using jQuery or native browser API (domElement.addEventListener) to handle events, you have to adapt your coding to support both.
In addition, emulated mouse events shouldn't be handled otherwise the event handler is called twice for the touch. This can be achieved by checking the flag (_sapui_delayedMouseEvent) we set to the emulated mouse events. We have extended the jQuery.Event object with isMarked function for checking UI5 specific flags on the real event object. The sapui prefix is already considered within the isMarked function so only the semantic part needs to be passed into the function (for example, for checking if the flag _sapui_delayedMouseEvent is marked, simply call isMark (delayedMouseEvent)). But when event handler is bound using browser API like addEventListener, flag needs to be checked by using the full flag name since there's no isMarked function on the browser event object.
In most of the cases, the event handler was bound by checking if touch is supported, like the code below:
jQuery(document).on(sap.ui.Device.support.touch ? "touchmove" : "mousemove", function(oEvent) { ...... });
When using jQuery:
jQuery(document).on("touchmove mousemove", function(oEvent) { if (oEvent.isMarked("delayedMouseEvent")) { // Suppress the emulated mouse event from touch interface return; } ...... });
When using native browser event listeners:
var fnHandler = function (oEvent ) { if (oEvent . _sapui_delayedMouseEvent ) { // Suppress the emulated mouse event from touch interface return ; } ...... }; document . addEventListener ( "touchmove" , fnHandler ); document . addEventListener ( "mousemove" , fnHandler );
We have also adapted some controls within sap.m for Windows 8 support. Let's take sap.m.RatingIndicator as an example. User can drag the rating indicator to change the rating value. This is implemented by registering to touchmove or mousemove event in ontouchstart function and deregister from touchmove or mousemove by listening to touchend, touchcancel or mouseup.
Before the adaptation, code was:
sap.m.RatingIndicator.prototype.ontouchstart = function(oEvent) { if (this.getEnabled()) { ...... if (!this._touchEndProxy) { this._touchEndProxy = jQuery.proxy(this._ontouchend, this); } if (!this._touchMoveProxy) { this._touchMoveProxy = jQuery.proxy(this._ontouchmove, this); } // here also bound to the mouseup mousemove event to enable it working in // desktop browsers if (sap.ui.Device.support.touch) { jQuery(window.document).on("touchend touchcancel", this._touchEndProxy); jQuery(window.document).on("touchmove", this._touchMoveProxy); } else { jQuery(window.document).on("mouseup", this._touchEndProxy); jQuery(window.document).on("mousemove", this._touchMoveProxy); } ...... } }; sap.m.RatingIndicator.prototype._ontouchmove = function(oEvent) { ...... }; sap.m.RatingIndicator.prototype._ontouchend = function(oEvent) { if (this.getEnabled()) { ...... if (sap.ui.Device.support.touch) { jQuery(window.document).off("touchend touchcancel", this._touchEndProxy); jQuery(window.document).off("touchmove", this._touchMoveProxy); } else { jQuery(window.document).off("mouseup", this._touchEndProxy); jQuery(window.document).off("mousemove", this._touchMoveProxy); } ...... } };
After the code adaptation:
sap.m.RatingIndicator.prototype.ontouchstart = function(oEvent) { if (this.getEnabled()) { ...... if (!this._touchEndProxy) { this._touchEndProxy = jQuery.proxy(this._ontouchend, this); } if (!this._touchMoveProxy) { this._touchMoveProxy = jQuery.proxy(this._ontouchmove, this); } // here also bound to the mouseup mousemove event to enable it working in // desktop browsers if (sap.ui.Device.support.touch) { jQuery(window.document).on("touchend touchcancel", this._touchEndProxy); jQuery(window.document).on("touchmove", this._touchMoveProxy); } else { jQuery(window.document).on("mouseup", this._touchEndProxy); jQuery(window.document).on("mousemove", this._touchMoveProxy); } ...... } }; sap.m.RatingIndicator.prototype._ontouchmove = function(oEvent) { ...... }; sap.m.RatingIndicator.prototype._ontouchend = function(oEvent) { if (this.getEnabled()) { ...... if (sap.ui.Device.support.touch) { jQuery(window.document).off("touchend touchcancel", this._touchEndProxy); jQuery(window.document).off("touchmove", this._touchMoveProxy); } else { jQuery(window.document).off("mouseup", this._touchEndProxy); jQuery(window.document).off("mousemove", this._touchMoveProxy); } ...... } };