标准的移动端事件,只有这三个:touchstart / touchMove / touchEnd 。但是这三个事件都无法满足正常的需求,我们都是通过这三个事件来模拟出移动端的点击、双击、长按、滑动、缩放等事件的。

1. touch 事件对象

  • targetTouches / touches ,这两个属性部分手机只有其中一个,所以需要做兼容处理

  • changedTouches

存储的是一个 TouchList 类性的类数组,存储的是手指操作的信息集合,集合中记录了每一根操作的手指的相关信息(包含触发点的坐标位置),一个手指操作就只有一个元素,多个手指操作,就是多个元素。每个元素都是一个 Touch 类型对象。

touches 记录的信息只有手指在屏幕上的时候才有,手指离开屏幕的时候信息就消失了,而 changedTouches 本意上记录的是改变的值,即手指离开,信息值也在,所以更多的使用 changedTouches

  1. box.ontouchstart = function (e) {
  2. //=> 记录按下的时候手指的起始位置
  3. let point = e.changedTouches[0];
  4. this.strX = point.clientX;
  5. this.strY = point.clientY;
  6. this.isMove = false;
  7. };

2. 模仿移动端的点击事件

移动端中 CLICK 事件是单击事件,当触发点击操作,浏览器总会等待 300ms ,验证是否触发了第二次点击操作,没有触发才会执行 CLICK 对应的方法,就会存在 300MS 的延迟

  • 不建议在移动端使用 CLICK(如果非要使用,最好导入插件 fastclick.min.js 就是解决 300ms 延迟的插件)

  • 目前项目中,移动端的点击操作基本上都是基于第三方类库(事件库完成的)

    • zepto:提供了移动端常用的事件操作

    • touch.js

    • hammer.js

zepto 中提供的专门供移动端操作的事件方法

  1. $box.tap(e => {
  2. //=> 点击
  3. });
  4. $box.singleTap(e => {
  5. //=> 单击
  6. });
  7. $box.doubleTap(e => {
  8. //=> 双击
  9. });
  10. $box.longTap(e => {
  11. //=> 长按
  12. });
  13. //=> swipe / swipeLeft / swipeRight / swipeUp / swipeDown 滑动
  14. //=> pinchIn / pinchOut... 双指操作缩放

这些插件和类库都是基于 touch、gestrue 等原生手指事件来模拟 点击、长按、滑动等事件。

简单的模拟

  1. box.ontouchstart = function (e) {
  2. //=> 记录按下的时候手指的起始位置
  3. let point = e.changedTouches[0];
  4. this.strX = point.clientX;
  5. this.strY = point.clientY;
  6. this.isMove = false;
  7. };
  8. box.ontouchmove = fucntion (e) {
  9. let point = e.changedTouches[0];
  10. this.changeX = point.clientX - this.strX;
  11. this.chengeY = point.clientY - this.strY;
  12. if(Math.abs(this.changeX) > 10 || Math.abs(this.changeY) > 10) {
  13. //=> 10 是操作误差值
  14. this.isMove = true;
  15. }
  16. };
  17. box.ontouchend = function (e) {
  18. if (this.isMove) {
  19. //=> 属于滑动,不是点击,可以通过 changeX、changeY 的正负来判断滑动方向
  20. return;
  21. }
  22. //=> 点击
  23. console.log('点击操作');
  24. }

长按事件模拟,通过记录按下时间和在离开的时候清除这个记录,如果在 750ms 内手指没有离开,那就是长按事件。

单击、双击事件模拟,通过设置定时器,如果在 300ms 内再次触发,则是双击,如果没有则是点击。