小程序从入门到入坑:事件系统

前言

哈喽大家好,我是 SuperYing ,本文是小程序从入门到入坑 系列的第 3 篇,将比较详尽的讲解 小程序事件系统 的相关知识点,欢迎小伙伴阅读。

读完本文您将收获:

  1. 了解小程序事件及基础使用。
  2. 了解小程序事件分类及多种的绑定方式。
  3. 了解如何使用 wxs 绑定事件响应函数。

什么是事件

借用官网的描述:

  • 事件是视图层到逻辑层的通讯方式。
  • 事件可以将用户的行为反馈到逻辑层进行处理。
  • 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
  • 事件 对象可以携带额外信息,如 id, dataset, touches

事件 可以完成从 视图层逻辑层 的通信,通过特定的参数处理方式,实现对于用户行为的逻辑处理。

事件绑定

事件分类

小程序事件分为:

  • 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
  • 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。

WXML 的冒泡事件列表:

类型 触发条件 最低版本
touchstart 手指触摸动作开始
touchmove 手指触摸后移动
touchcancel 手指触摸动作被打断,如来电提醒,弹窗
touchend 手指触摸动作结束
tap 手指触摸后马上离开
longpress 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发 1.5.0
longtap 手指触摸后,超过350ms再离开(推荐使用longpress事件代替)
transitionend 会在 WXSS transition 或 wx.createAnimation 动画结束后触发
animationstart 会在一个 WXSS animation 动画开始时触发
animationiteration 会在一个 WXSS animation 一次迭代结束时触发
animationend 会在一个 WXSS animation 动画完成时触发
touchforcechange 在支持 3D Touch 的 iPhone 设备,重按时会触发 1.9.90

注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 formsubmit事件,inputinput事件,scroll-viewscroll事件,(详见各个组件)

普通事件绑定

事件绑定的写法类似于组件的属性,在 bind:(冒号 : 可省略) 后面加上事件名称:

bind:[事件名称]="[事件绑定函数名称]"

事件绑定函数名称 是一个字符串,指向在 .ts/.js 文件的 Page 函数中定义的处理函数名。

eg:

html 复制代码
<view bind:tap="handleTap">点击区域</view>

事件绑定函数名称 也可以是数据绑定,但是绑定的变量必须是一个字符串 ,指向事件处理函数名。若该变量为空字符串,则绑定会失效,可以该特性来暂时禁用某些事件。

html 复制代码
<view bind:tap="{{ tapHandlerName }}">点击区域</view>
js 复制代码
Page({
    data: {
        tapHandlerName: 'handleTap'
    },
    
    handleTap() {
        // tap 事件处理逻辑...
    }
})

阻止事件冒泡绑定

除了使用 bind 绑定事件,还可以使用 catch 绑定。两者区别在于 catch 会事件向上冒泡。

「事件分类」part 我们知道,小程序事件有一种冒泡事件,此类事件触发后会向父节点传递。

eg:

html 复制代码
<view id="outer" bind:tap="handleTap1">
  outer view
  <view id="middle" catch:tap="handleTap2">
    middle view
    <view id="inner" bind:tap="handleTap3">
      inner view
    </view>
  </view>
</view>

上例中,点击 inner view 会先后调用 handleTap3handleTap2,这是因为 tap 事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递.点击 middle view 会触发 handleTap2,点击 outer view 会触发 handleTap1

互斥事件绑定

除了 bindcatch 外,还可以使用 mut-bind 来绑定互斥事件,所有 mut-bind 绑定都是互斥的,只会触发其中一个绑定函数,但是不会影响bindcatch 绑定的事件。

也就是说,触发 mut-bind 绑定的事件后,如果事件冒泡到父级节点上,在父级节点上使用 mut-bind 绑定的事件不会被触发,而使用 bindcatch 绑定的事件可以正常触发。

eg:

html 复制代码
<view id="outer" mut-bind:tap="handleTap1">
  outer view
  <view id="middle" bindtap="handleTap2">
    middle view
    <view id="inner" mut-bind:tap="handleTap3">
      inner view
    </view>
  </view>
</view>

上例中,点击 inner view 会先后调用 handleTap3handleTap2,因为 handleTap3handleTap1 绑定的事件互斥,所以冒泡到 outer 时不会触发 handleTap1。点击 middle view 会调用 handleTap2handleTap1

事件捕获阶段绑定

小程序的触摸类事件 支持捕获阶段。捕获阶段发生在冒泡事件之前,事件到达节点的顺序与冒泡阶段恰好相反。

对于 DOM 事件比较了解的小伙伴应该比较清楚,支持捕获阶段的事件触发流程如下: 可以通过 capture-bindcapture-catch 来在捕获阶段绑定事件,其中 capture-catch中断捕获阶段并取消冒泡阶段

html 复制代码
<view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2">
  outer view
  <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
    inner view
  </view>
</view>

上例中,点击 inner view 会先后调用 handleTap2handleTap4handleTap3handleTap1

若将上例中的 capture-bind:touchstart="handleTap2" 改为 capture-catch:touchstart="handleTap2",将会仅触发 handleTap2

eg:

html 复制代码
<view id="outer" bind:touchstart="handleTap1" capture-catch:touchstart="handleTap2">
  outer view
  <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
    inner view
  </view>
</view>

wxs 绑定响应函数

在上一篇 框架语法 中我们有提到小程序的脚本语言 wxs。我们可以在 wxs 中创建事件处理参数,绑定到指定事件上(注意:仅能响应内置组件的事件,不支持自定义事件)。

使用 wxs 绑定响应函数,主要是用来优化频繁交互的场景,将事件响应放到视图层 ,避免视图层逻辑层频繁通信,导致交互过程的延迟。

wxs 的事件处理函数包括两个参数:

  • event : 事件对象,在 小程序事件对象 的基础上,多了一个 instance 属性,用来表示触发事件结构的 ComponentDescriptor 实例。
  • ownerInstance : 触发事件的组件所在的组件的 ComponentDescriptor 实例,如果触发事件的组件在页面内,ownerInstance 表示的是页面实例。

ComponentDescriptor 是小程序内部封装的类,包括 selectComponent, selectAllComponents, setStyle, addClass/removeClass/hasClass, callMethod 等实例方法,可用于获取页面组件实例,设置组件样式,与逻辑层交互等功能。

eg:

html 复制代码
// index.wxml
<wxs module="tools" src="./tools.wxs"></wxs>
<view id="tapTest" data-hi="微信小程序" bindtap="{{tools.tapName}}"> Click me! </view>
js 复制代码
// tools.wxs
function tapName(event, ownerInstance) {
  console.log('tap 事件', JSON.stringify(event))
}
module.exports = {
  tapName: tapName
}

结语

好啦,今天我们整体性的讲述了 小程序事件系统 相关的内容。相信读到这里的小伙伴已经对 小程序事件系统 有了比较清晰的了解,爱动手的小伙伴们快去动起来吧😁。

若有疑问,欢迎评论区。感谢阅读!愿你我共同进步,谢谢!!!

相关推荐
恋猫de小郭8 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅14 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606115 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了15 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅15 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅15 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅16 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment16 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅16 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊16 小时前
jwt介绍
前端