You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Nice polyfill. I noticed that you set lastTouchTime = Date.now() on each touch event and then check if the mouse event comes in within 1000ms of the last touch event to determine if the mouse event was from a touch interaction. This works most of the time (I used this technique in the-listener), except when the touch event starts a blocking process that takes longer than 1000ms. The mouse event will come in after the 1000ms and won't be recognized as originating from a touch interaction.
To fix this, I used a setTimeout to take advantage of the browser's multithreading capabilities.
varrecentTouch=false;vartouchTimerID=null;functiontouchHandler(event){recentTouch=true;// only have one timer running at a time, otherwise recentTouch could be set to false// from an earlier touch while the most recent touch event's timer is still running, so// clear the timer when a touch event comes in before the previous event's timer endsif(touchTimerID!==null)window.clearTimeout(touchTimerID);touchTimerID=window.setTimeout(function(){touchTimerID=null;recentTouch=false;// 1000ms may be longer than is needed with this technique},600)}
And then use recentTouch to determine if a mouse event is from a touch interaction.
Note that in the case of a long blocking process from a touch event, the browser will push the corresponding mouse event onto the queue when it should be executed (anywhere from a few ms to 300+), and then push the timeout function onto the queue after the timer expires. This results in the mouse event being pushed onto the callstack and executed before the timeout function, even if it isn't executed until several seconds later, so it's recognized as a mouse event from a touch interaction.
Also, if subsequent touch events occur while the blocking process is running, the browser will push the touch events onto the queue when the touch happens, and if one of them is in queue before the previous touch event's timer expires, it will execute before the timeout's function, and, this is the key part, the call to clearTimeout(touchTimerID) will remove the timeout's function from the queue even after the timer has finished (I did some testing for this scenario when I came up with the solution because I wasn't sure, but it appears to be the case).
Hope you find this useful.
The text was updated successfully, but these errors were encountered:
Also, in my experience you only need to set a timer on touchend, as well as keep track of if there is a touch point currently on the screen as mouse events from touch interactions only fire after touchend, and, on Chrome on Android and Windows, on long press while still touching the screen (the latter I think is to simulate mouse hover functionality, but you would know better than I would). You could use an extra long timer set on touchstart to ignore the mouse events from a long press, but to me it made more sense to just keep track of if there is a touch point currently on the screen.
Nice polyfill. I noticed that you set
lastTouchTime = Date.now()
on each touch event and then check if the mouse event comes in within 1000ms of the last touch event to determine if the mouse event was from a touch interaction. This works most of the time (I used this technique inthe-listener
), except when the touch event starts a blocking process that takes longer than 1000ms. The mouse event will come in after the 1000ms and won't be recognized as originating from a touch interaction.To fix this, I used a
setTimeout
to take advantage of the browser's multithreading capabilities.And then use
recentTouch
to determine if a mouse event is from a touch interaction.Note that in the case of a long blocking process from a touch event, the browser will push the corresponding mouse event onto the queue when it should be executed (anywhere from a few ms to 300+), and then push the timeout function onto the queue after the timer expires. This results in the mouse event being pushed onto the callstack and executed before the timeout function, even if it isn't executed until several seconds later, so it's recognized as a mouse event from a touch interaction.
Also, if subsequent touch events occur while the blocking process is running, the browser will push the touch events onto the queue when the touch happens, and if one of them is in queue before the previous touch event's timer expires, it will execute before the timeout's function, and, this is the key part, the call to
clearTimeout(touchTimerID)
will remove the timeout's function from the queue even after the timer has finished (I did some testing for this scenario when I came up with the solution because I wasn't sure, but it appears to be the case).Hope you find this useful.
The text was updated successfully, but these errors were encountered: