Fix swipe and popup contextmenu being triggered accidentally in touch devices

This commit is contained in:
hadi 2023-06-01 15:28:42 +02:00
parent 1d4bc10fbb
commit 8e0a3a2755
4 changed files with 45 additions and 30 deletions

View File

@ -290,7 +290,7 @@ export function egwPopupActionImplementation()
let tap = new tapAndSwipe(_node, {
// this threshold must be the same as the one set in et2_dataview_view_aoi
tapHoldThreshold: 600,
tapHoldThreshold: 1000,
allowScrolling: "both",
tapAndHold: function(event, fingercount)
{

View File

@ -117,10 +117,10 @@ export function et2_dataview_rowAOI(_node)
if (egwIsMobile()) {
let swipe = new tapAndSwipe(_node,{
// set the same threshold as action_popup event to get the tapAndHold working
tapHoldThreshold: 600,
tapHoldThreshold: 1000,
swipe: function (event, direction, distance)
{
if (distance > 100) selectHandler(event, {swip:direction});
selectHandler(event, {swip:direction});
},
tap: function (event)
{

View File

@ -11,7 +11,7 @@ export interface TapAndSwipeOptions {
// allow scrolling would stop swipe/tap events from being fired when there's scrolling available. It can be restricted
// to Vertical/Horizental/Both scrolling. If no value set it means not allowed.
allowScrolling? : string|null,
// tolorated pixel to fire the swipe events
// tolorated pixel for tap event
threshold? : number,
// time delay for defirentiate between tap event and long tap event, threshold is in milliseconds
tapHoldThreshold? : number,
@ -23,6 +23,8 @@ export interface TapAndSwipeOptions {
tap? : Function,
// callback function being called on long tap(tap and hold)
tapAndHold? : Function,
// tolerate pixel to fire swipe events
minSwipeThreshold? : number,
}
export type TapAndSwipeOptionsType = TapAndSwipeOptions;
@ -31,6 +33,7 @@ export class tapAndSwipe {
static readonly _default : TapAndSwipeOptionsType = {
threshold : 5,
tapHoldThreshold : 3000,
minSwipeThreshold: 150,
allowScrolling : 'both',
swipe : function(){},
tap : function(){},
@ -57,10 +60,17 @@ export class tapAndSwipe {
*/
private _endY : number = null;
/**
* keeps the distance travelled between start point and end point
* keeps the distance travelled between startX point and endX point
* @private
*/
private _distance : number = null;
private _distanceX : number = null;
/**
* keeps the distance travelled between startY point and endY point
* @private
*/
private _distanceY : number = null;
/**
* flag to keep the status of type of tap
* @private
@ -86,6 +96,9 @@ export class tapAndSwipe {
private _hasBeenScrolled : boolean = false;
private _scrollEventTriggered : boolean = false;
private _stillMoving : boolean = false;
/**
* Options
* @protected
@ -131,7 +144,7 @@ export class tapAndSwipe {
_onTouchMove(event)
{
this._stillMoving = true;
}
/**
* on touch start event handler
@ -140,8 +153,8 @@ export class tapAndSwipe {
*/
private _onTouchStart(event : TouchEvent)
{
this._startX = event.changedTouches[0].screenX;
this._startY = event.changedTouches[0].screenY;
this._startX = event.changedTouches[0].pageX;
this._startY = event.changedTouches[0].pageY;
this._isTapAndHold = false;
this._fingercount = event.touches.length;
@ -165,7 +178,7 @@ export class tapAndSwipe {
this._tapHoldTimeout = window.setTimeout(_=>{
this._isTapAndHold = true;
//check scrolling
if (this.options.allowScrolling && this._hasBeenScrolled)
if (this.options.allowScrolling && this._stillMoving)
{
return;
}
@ -181,8 +194,9 @@ export class tapAndSwipe {
*/
private _ontouchEnd(event : TouchEvent)
{
this._endX = event.changedTouches[0].screenX;
this._endY = event.changedTouches[0].screenY;
this._endX = event.changedTouches[0].pageX;
this._endY = event.changedTouches[0].pageY;
this._stillMoving = false;
if (this._scrolledElementObj) {
switch (this.options.allowScrolling)
@ -218,10 +232,13 @@ export class tapAndSwipe {
{
//cleanup tapHoldTimeout
window.clearTimeout(this._tapHoldTimeout);
this._distanceX = Math.abs(this._endX-this._startX);
this._distanceY = Math.abs(this._endY-this._startY);
const isTabOrHold = (this._endX == this._startX && this._endY == this._startY
|| (Math.sqrt((this._endX-this._startX)*(this._endX-this._startX) + (this._endY-this._startY)+(this._endY-this._startY))
|| (Math.sqrt((this._distanceX)*(this._distanceX) + (this._distanceY*2))
< this.options.threshold));
this._hasBeenScrolled = this._hasBeenScrolled ?? (!isTabOrHold && this._scrollEventTriggered);
//check scrolling
if (this.options.allowScrolling && this._hasBeenScrolled)
@ -231,13 +248,11 @@ export class tapAndSwipe {
}
// Tap & TapAndHold handler
if (this._endX == this._startX && this._endY == this._startY
|| (Math.sqrt((this._endX-this._startX)*(this._endX-this._startX) + (this._endY-this._startY)+(this._endY-this._startY))
< this.options.threshold))
if (isTabOrHold)
{
if (!this._isTapAndHold)
{
this._tapHoldTimeout = window.setTimeout(_=> {
this._tapTimeout = window.setTimeout(_=> {
this.options.tap.call(this,event, this._fingercount);
}, 100);
}
@ -246,30 +261,30 @@ export class tapAndSwipe {
}
// left swipe handler
if (this._endX + this.options.threshold < this._startX) {
this._distance = this._startX - this._endX;
this.options.swipe.call(this, event, 'left', this._distance, this._fingercount);
if (this._endX + this.options.threshold < this._startX && this._distanceX > this._distanceY) {
if (this._distanceX < this.options.minSwipeThreshold) return;
this.options.swipe.call(this, event, 'left', this._distanceX, this._fingercount);
return;
}
// right swipe handler
if (this._endX - this.options.threshold > this._startX) {
this._distance = this._endX - this._startX;
this.options.swipe.call(this, event, 'right', this._distance, this._fingercount);
if (this._endX - this.options.threshold > this._startX && this._distanceX > this._distanceY) {
if (this._distanceX < this.options.minSwipeThreshold) return;
this.options.swipe.call(this, event, 'right', this._distanceX, this._fingercount);
return;
}
// up swipe handler
if (this._endY + this.options.threshold < this._startY) {
this._distance = this._startY - this._endY;
this.options.swipe.call(this, event, 'up', this._distance, this._fingercount);
if (this._endY + this.options.threshold < this._startY && this._distanceY > this._distanceX) {
if (this._distanceY < this.options.minSwipeThreshold) return;
this.options.swipe.call(this, event, 'up', this._distanceY, this._fingercount);
return;
}
// down swipe handler
if (this._endY - this.options.threshold > this._startY) {
this._distance = this._endY - this._startY;
this.options.swipe.call(this, event, 'down', this._distance, this._fingercount);
if (this._endY - this.options.threshold > this._startY && this._distanceY > this._distanceX) {
if (this._distanceY < this.options.minSwipeThreshold) return;
this.options.swipe.call(this, event, 'down', this._distanceY, this._fingercount);
return;
}
}

View File

@ -1287,7 +1287,7 @@ export class CalendarApp extends EgwApp
scroll_animate.call(jQuery(event.target).closest('.calendar_calTimeGrid, .calendar_plannerWidget')[0], direction, delta);
return false;
},
threshold: 100,
minSwipeThreshold: 100,
allowScrolling: 'vertical'
});