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

前言

哈喽大家好,我是 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
}

结语

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

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

相关推荐
gqkmiss15 分钟前
Chrome 浏览器 131 版本开发者工具(DevTools)更新内容
前端·chrome·浏览器·chrome devtools
Summer不秃20 分钟前
Flutter之使用mqtt进行连接和信息传输的使用案例
前端·flutter
旭日猎鹰25 分钟前
Flutter踩坑记录(二)-- GestureDetector+Expanded点击无效果
前端·javascript·flutter
Viktor_Ye31 分钟前
高效集成易快报与金蝶应付单的方案
java·前端·数据库
hummhumm33 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
乐闻x1 小时前
Vue.js 性能优化指南:掌握 keep-alive 的使用技巧
前端·vue.js·性能优化
一条晒干的咸魚1 小时前
【Web前端】创建我的第一个 Web 表单
服务器·前端·javascript·json·对象·表单
Amd7941 小时前
Nuxt.js 应用中的 webpack:compiled 事件钩子
前端·webpack·开发·编译·nuxt.js·事件·钩子
生椰拿铁You1 小时前
09 —— Webpack搭建开发环境
前端·webpack·node.js
狸克先生2 小时前
如何用AI写小说(二):Gradio 超简单的网页前端交互
前端·人工智能·chatgpt·交互