touchstart 事件在 iOS 上为啥不生效?

程序员国曼 阅读 47

我在做一个移动端的滑动组件,用了 touchstart 监听开始触摸,但在 iPhone 上完全没反应,安卓倒是正常的。

试过加 passive: false,也试过给元素加 touch-action: none,还是不行。是不是 iOS 有啥特殊限制?

相关代码是这样的:

const el = document.getElementById('slider');
el.addEventListener('touchstart', (e) => {
  console.log('touch started');
  e.preventDefault();
}, { passive: false });
我来解答 赞 7 收藏
二维码
手机扫码查看
2 条解答
建利酱~
这个问题在 iOS Safari 上挺常见的,不是你的代码写法有问题,而是 iOS 对可交互元素有个隐藏的坑:它要求元素必须具备"可点击"的属性才会在某些情况下触发 touch 事件。

最直接的解决方案:给元素加个 cursor: pointer

#slider {
cursor: pointer;
/* 或者用这个 */
-webkit-tap-highlight-color: transparent;
}


如果还不行,试试给元素先绑一个空的 click 事件,这是 iOS 的一个怪癖:

const el = document.getElementById('slider');

// 先绑个空 click,iOS 需要这个"激活" touch 事件
el.addEventListener('click', () => {});

el.addEventListener('touchstart', (e) => {
console.log('touch started');
e.preventDefault();
}, { passive: false });


另外检查一下:你的代码是在 DOMContentLoaded 或者 jQuery 的 ready 回调里写的吗?如果在主题里用,得确保执行时机没问题,很多人在这翻车。

还有一种情况是如果 slider 元素是动态生成的(比如 Ajax 加载出来的),那得在生成之后才绑定事件,别绑在空元素上。
点赞
2026-03-18 20:06
爱学习的晨旭
这个问题我之前做移动端项目也踩过坑,iOS 对 touch 事件的触发条件比安卓严格很多。

最可能的原因是你的目标元素不是"可交互元素"。iOS 默认情况下,普通的 div、span 这类元素是不会触发 touchstart 的,只有 button、a、input 这类原生可交互元素才行。

解决办法很简单,给这个元素加个 CSS 属性让它变成可交互:

#slider {
cursor: pointer;
}


或者用 JS 直接设置:

const el = document.getElementById('slider');
el.style.cursor = 'pointer'; // 关键,让 iOS 认为这是可交互元素
el.addEventListener('touchstart', (e) => {
console.log('touch started');
e.preventDefault();
}, { passive: false });


iOS 的逻辑是这样的:它需要明确知道这个元素是"可以点的",才会把触摸事件传递给它。安卓没这个限制,所以你那边安卓正常、iOS 挂了。

另外提一嘴,touch-action: none 这个属性慎用,它会完全禁用浏览器默认的触摸行为,包括滚动和缩放。如果你这个滑动组件是在页面滚动区域里,可能会把整个页面的滚动都搞没。

试试加 cursor: pointer,应该就能解决了。
点赞 6
2026-03-01 17:34