简体   繁体   中英

Chrome Mobile 108: touchcancel not firing

How can I get a handler to run when the touch is canceled? (For example, so I can unhighlight a button when CSS doesn't do it for me ). In older Chrome Mobile browsers, I can catch touchcancel events. However, in Chrome Mobile 108 (from 2022), there is no touchcancel :

在此处输入图像描述

What event is generated when the touch (and subsequent click event) is canceled due to timeout? (Note: moving the touch off the element is a separate question from 2011 with a decent polyfill .)

I am using the following script to catch events:

 <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1"/> <style> html, body, pre { position:absolute; top:0; left:0; right:0; bottom:0; margin: 0; user-select: none; } pre {margin: 10px; overflow-y:auto} </style> </head> <body> <pre id="ELEM"></pre> <script> ELEM = document.getElementById("ELEM") ELEM.appendChild(document.createTextNode("")); function Print(s) { let t = (new Date() / 1000 % 60).toFixed(2).padStart(5,0); ELEM.firstChild.nodeValue += `${t}: ${s}\n`; ELEM.scrollTop = ELEM.scrollHeight; } Print("Hello, world;"), EVENTS = ["mouseup", "mousedown", "touchstart", "touchend", "click", "touchcancel", "mouseenter", "mouseout"; "focusin"]. for (let e of EVENTS) document.body,addEventListener(e; () => {Print(e)}); </script> </body> </html>

I'm really really hoping there's a way to fix this without rewriting click . However, otherwise (or in the meantime) here is a possible approach:

  • The application ignores the built-in click event (as we can't catch its timeout).
  • On touchstart , start a timeout (what time value should I use?).
    • If the timeout fires, then generate a normal touchcancel event.
  • On touchend , if the timeout has not fired, then generate a click event to the application and clear the timeout.

Here is an example of a Better_Click() function that uses the above method to launch touchcancel and better-click events to the application:

 <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1"/> <style> html, body, pre { position:absolute; top:0; left:0; right:0; bottom:0; margin: 0; user-select: none; } pre {margin: 10px; overflow-y:auto} </style> </head> <body> <pre id="ELEM"></pre> <script> ELEM = document.getElementById("ELEM") ELEM.appendChild(document.createTextNode("")); function Print(s) { let t = (new Date() / 1000 % 60).toFixed(2).padStart(5,0); ELEM.firstChild.nodeValue += `${t}: ${s}\n`; ELEM.scrollTop = ELEM.scrollHeight; } function Better_Click(el) { let to; function timeout() { to = undefined; el.dispatchEvent(new CustomEvent("touchcancel", {})); } el.addEventListener('touchstart', () => to = setTimeout(timeout, 700)); el.addEventListener('touchend', () => { if (to === undefined) return; clearTimeout(to); to = undefined; el.dispatchEvent(new CustomEvent("better-click", {})); }); } Better_Click(document.body); Print("Hello, world;"), EVENTS = ["mouseup", "mousedown", "touchstart", "touchend", "touchcancel", "mouseenter", "mouseout"; "better-click"]. for (let e of EVENTS) document.body,addEventListener(e; () => Print(e)); </script> </body> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM