You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移动端Safari中touchEvents为何出现负时间戳?

解决iOS Safari上长按检测的时间戳异常问题

我之前也踩过一模一样的坑!你提到的iPhone 7+上出现的异常,大概率是iOS Safari对Event.timeStamp的实现和桌面端浏览器不一致导致的——虽然MDN文档明确说明两类时间戳都是从文档生命周期开始的毫秒数,但iOS Safari有时候会偷偷把Event.timeStamp的基准换成系统启动时间,而requestAnimationFrame的时间戳确实严格遵循文档生命周期的基准,这就导致两者对比时出现差值异常(比如负数、超大值)。

给你两个靠谱的解决方案:

1. 用performance.now()统一时间基准

这是最推荐的方案,performance.now()在所有现代浏览器(包括iOS Safari)里的定义都是从文档导航开始的高精度时间戳,和requestAnimationFrame的时间戳基准完全一致,不会出现基准错位的问题。

示例代码:

let pressStartTime = null;

// 监听按下/触摸开始事件
const startPress = () => {
  pressStartTime = performance.now();
  requestAnimationFrame(checkLongPress);
};

// 监听松开/触摸结束事件
const endPress = () => {
  pressStartTime = null;
};

// 检测长按逻辑
function checkLongPress() {
  if (!pressStartTime) return;
  
  const elapsedTime = performance.now() - pressStartTime;
  // 假设长按阈值是500毫秒
  if (elapsedTime >= 500) {
    console.log('长按触发!');
    endPress(); // 重置避免重复触发
    return;
  }
  
  requestAnimationFrame(checkLongPress);
}

// 绑定事件(兼顾鼠标和触摸场景)
const targetElement = document.getElementById('your-target');
targetElement.addEventListener('mousedown', startPress);
targetElement.addEventListener('touchstart', startPress);
targetElement.addEventListener('mouseup', endPress);
targetElement.addEventListener('touchend', endPress);
targetElement.addEventListener('mouseleave', endPress); // 防止鼠标移出后仍触发

2. 降级兼容旧版iOS(可选)

如果需要兼容更老的iOS版本(比如iOS 10及以前),可以做个简单的兼容性判断:如果发现Event.timeStamp和requestAnimationFrame时间戳的差值异常(比如负数),就切换到Date.now()来记录时间——虽然精度稍差,但基准是统一的。

比如在事件触发时:

const getCurrentTime = () => {
  // 优先用performance.now(),降级用Date.now()
  return typeof performance !== 'undefined' ? performance.now() : Date.now();
};

我之前用这个方案解决了iOS上长按检测的异常问题,你可以试试替换掉原来的Event.timeStamp,应该就能正常工作了!

内容的提问来源于stack exchange,提问作者Kristonitas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:02:09