Chrome 第一百零八章:触摸取消不激发

dfddblmv  于 2022-12-20  发布在  Go
关注(0)|答案(1)|浏览(89)

如何让处理程序在取消触摸时运行?(例如,这样我就可以在CSS没有为我取消高亮显示按钮时取消高亮显示按钮)。在较旧的Chrome移动的浏览器中,我可以捕捉touchcancel事件。但是,在Chrome移动108(从2022年开始)中,没有touchcancel

当触摸(以及后续click事件)因超时而取消时,将生成什么事件?(注:将触摸从元素移开是separate question from 2011decent polyfill。)
我使用以下脚本来捕获事件:

<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>
bhmjp9jg

bhmjp9jg1#

我真的很希望有一种方法可以在不重写click的情况下解决这个问题。

  • 应用程序忽略内置的click事件(因为我们无法捕捉它的超时)。
  • touchstart上,启动一个超时(应该使用什么时间值?)
  • 如果触发超时,则生成正常的touchcancel事件。
  • touchend上,如果未触发超时,则向应用程序生成一个单击事件并清除超时。

以下是Better_Click()函数的示例,该函数使用上述方法向应用程序启动touchcancelbetter-click事件:

<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>

相关问题