【移动端】事件基础

一、移动端事件分类

移动端事件主要分为以下几类:

1. 触摸事件(Touch Events)

触摸事件是移动设备特有的事件,用来处理用户通过触摸屏幕进行的操作。主要的触摸事件有:

  • touchstart:手指触摸屏幕时触发。
  • touchmove:手指在屏幕上滑动时持续触发。
  • touchend:手指离开屏幕时触发。
  • touchcancel:当触摸被意外中断时(例如电话呼入、页面被打断),触发该事件。

触摸事件对应的监听方法:

javascript 复制代码
element.addEventListener('touchstart', handleTouchStart);
element.addEventListener('touchmove', handleTouchMove);
element.addEventListener('touchend', handleTouchEnd);
element.addEventListener('touchcancel', handleTouchCancel);

2. 手势事件(Gesture Events)

部分移动端浏览器还支持手势事件,例如两个手指同时在屏幕上缩放或旋转。主要的手势事件有:

  • gesturestart:手势操作开始时触发。
  • gesturechange:手势在进行时持续触发。
  • gestureend:手势操作结束时触发。

这些事件通常依赖于多指触控的场景,如缩放(pinch)和旋转(rotate),但由于浏览器的支持不一,实际开发中应用较少。

3. 鼠标事件(Mouse Events)

尽管移动设备没有物理鼠标,但大多数移动设备的浏览器仍然支持传统的鼠标事件。常见的鼠标事件包括:

  • mousedown :手指接触屏幕时(与 touchstart 类似)。
  • mousemove :手指在屏幕上滑动时(与 touchmove 类似)。
  • mouseup :手指离开屏幕时(与 touchend 类似)。
  • click:手指快速点击屏幕时触发(综合了触摸和鼠标操作)。

二、事件对象

在移动端,触摸事件与鼠标事件最大的不同在于事件对象(Event Object),触摸事件有自己独特的事件属性。每个触摸事件对象都会包含一些特殊的信息,用于描述触摸的详细情况。

触摸事件对象的常用属性:

  • touches:当前屏幕上所有触点的列表(多点触控时包含所有触摸点)。
  • targetTouches:当前与目标元素相关的触点列表。
  • changedTouches:自上次触摸事件以来发生变化的触点列表。

每个触点对象(Touch 对象)包含以下属性:

  • clientX / clientY:触点相对于浏览器窗口的 X 和 Y 坐标。
  • screenX / screenY:触点相对于屏幕的 X 和 Y 坐标。
  • target:触点目标的 DOM 元素。

示例:处理触摸事件

javascript 复制代码
element.addEventListener('touchstart', function(event) {
    const touch = event.touches[0]; // 获取第一个触点
    console.log('Touch position: ', touch.clientX, touch.clientY);
});

举个例子:

比如div1、diw2只有div2绑定了touchstart事件,第一次放下一个手指在dv2上,触发了touchstart事件,这个时候,三个集合的内容是一样的,都包含这个手指的touch,然后,再放下两个手指一个在div1上,一个在div2上,这个时候又会触发事件,但changedTouches里面只包含第二个第三个手指的信息,因为第一个没有发生变化,而targetTouches包含的是在第一个手指和第三个在 div2上的手指集合,touches包含屏幕上所有手指的信息,也就是三个手指。

三、与 PC 端事件的区别

  1. 触摸事件 vs 鼠标事件

    • 触摸事件是多点触控的,可以同时处理多个触点(手指),而鼠标事件是单点事件,只能跟踪一个光标。
    • 移动端事件的触发顺序不同,常见顺序是:touchstart -> touchmove -> touchend,而鼠标事件的顺序是 mousedown -> mousemove -> mouseup
  2. 点击延迟

    • 在移动设备上,当用户点击屏幕时,浏览器会等待大约 300ms 以确定用户是否会进行双击操作。这是移动浏览器的默认行为,用于处理双击缩放。解决方法一:但是现在已经解决了这个问题,只要设置了 viewport 即可:

      html 复制代码
      <meta name="viewport" content="width=device-width, user-scalable=no">

      解决方法二:使用移动端专属的触摸事件,不使用 click ,也就自然不存在 300ms 问题。

  3. 默认行为的不同

    • 移动端浏览器会根据触摸操作做出一些默认行为,比如页面滚动、双指缩放等,可能会与页面的自定义逻辑冲突。因此,通常需要阻止这些默认行为。
    • 在触摸事件中可以通过 event.preventDefault() 来阻止默认的浏览器行为,例如页面滚动。

四、事件穿透

事件穿透(Event Penetration 或 Ghost Clicks) 是移动端上面一个非常有名的Bug,其出现场景为:有两层重叠的元素,上面的元素有 touch 事件(点击后要消失),下面是一个默认会触发 click 事件的元素(a、表单元素、带cick事件的壳素),此时点击上一层的元素,下一层也同样会被点击。

解决办法:

  • 使用 preventDefault() 阻止默认行为。
javascript 复制代码
element.addEventListener('touchend', function(event) {
    event.preventDefault();  // 阻止默认的click行为
    // 执行需要的逻辑
});

五、阻止默认事件带来的影响

移动端浏览器有一些默认行为,例如:

  • 页面滚动:当用户在屏幕上滑动时,页面会跟随手指滚动。
  • 双指缩放:用户可以通过双指操作缩放页面。
  • 长按菜单:用户长按某些元素时,会弹出上下文菜单。

阻止默认事件的作用:

  1. 防止页面滚动

    在某些交互场景下,例如全屏的游戏或拖动元素时,默认的页面滚动行为会干扰用户体验。通过在 touchmove 中调用 event.preventDefault() 可以阻止页面滚动。

    javascript 复制代码
    element.addEventListener('touchmove', function(event) {
        event.preventDefault(); // 禁止页面跟随手指滚动
    });
  2. 阻止双指缩放

    当页面需要固定缩放比例时,双指缩放会影响布局,可以通过以下方式阻止缩放行为:

    html 复制代码
    <meta name="viewport" content="width=device-width, user-scalable=no">
  3. 阻止长按弹出菜单

    用户长按图片或链接时,可能会弹出复制、保存等菜单,这对于某些 Web 应用来说是不必要的。可以通过阻止默认事件来禁用此功能。

    javascript 复制代码
    element.addEventListener('contextmenu', function(event) {
        event.preventDefault(); // 禁止长按弹出菜单
    });

还有一些其他影响等等。

实际上,移动端进行开发时一上来就需要阻止所有的默认事件,后面的很多功能都需要我们自定义来实现。

相关推荐
小白求学1几秒前
CSS计数器
前端·css
Anita_Sun9 分钟前
🌈 Git 全攻略 - Git 的初始设置 ✨
前端
等什么君!39 分钟前
复习HTML(进阶)
前端·html
儒雅的烤地瓜40 分钟前
JS | 如何解决ajax无法后退的问题?
前端·javascript·ajax·pushstate·popstate事件·replacestate
觉醒法师42 分钟前
Vue3+TS项目 - ref和useTemplateRef获取组件实例
开发语言·前端·javascript
老章学编程i1 小时前
Vue工程化开发
开发语言·前端·javascript·vue.js·前端框架
思考的橙子1 小时前
前端初识之一
前端
什么鬼昵称2 小时前
Pikachu-PHP反序列化
开发语言·javascript·php
tanxiaomi2 小时前
vue 不是spa 单页面应用吗? 配置路由工作模式为history 后 ,为什么配置Nginx的 try_files 可以根据url 找到对应的文件?
前端·vue.js·nginx
果子切克now2 小时前
vue3导入本地图片2种实现方法
前端·javascript·vue.js