前言
哈喽大家好,我是 SuperYing,本文是小程序从入门到入坑系列的第 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 |
注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 form 的
submit
事件,input 的input
事件,scroll-view 的scroll
事件,(详见各个组件)
普通事件绑定
事件绑定的写法类似于组件的属性,在 bind:
(冒号 :
可省略) 后面加上事件名称:
bind:[事件名称]="[事件绑定函数名称]"
事件绑定函数名称 是一个字符串,指向在 .ts/.js
文件的 Page
函数中定义的处理函数名。
eg:
<view bind:tap="handleTap">点击区域</view>
事件绑定函数名称也可以是数据绑定,但是绑定的变量必须是一个字符串,指向事件处理函数名。若该变量为空字符串,则绑定会失效,可以该特性来暂时禁用某些事件。
<view bind:tap="{{ tapHandlerName }}">点击区域</view>
Page({
data: {
tapHandlerName: 'handleTap'
},
handleTap() {
// tap 事件处理逻辑...
}
})
阻止事件冒泡绑定
除了使用 bind
绑定事件,还可以使用 catch
绑定。两者区别在于 catch
会事件向上冒泡。
在 「事件分类」part 我们知道,小程序事件有一种冒泡事件,此类事件触发后会向父节点传递。
eg:
<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
会先后调用 handleTap3
和 handleTap2
,这是因为 tap
事件会冒泡到 middle view
,而 middle view
阻止了 tap
事件冒泡,不再向父节点传递.点击 middle view
会触发 handleTap2
,点击 outer view
会触发 handleTap1
。
互斥事件绑定
除了 bind
和 catch
外,还可以使用 mut-bind
来绑定互斥事件,所有 mut-bind
绑定都是互斥的,只会触发其中一个绑定函数,但是不会影响bind
和 catch
绑定的事件。
也就是说,触发 mut-bind
绑定的事件后,如果事件冒泡到父级节点上,在父级节点上使用 mut-bind
绑定的事件不会被触发,而使用 bind
和 catch
绑定的事件可以正常触发。
eg:
<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
会先后调用 handleTap3
和 handleTap2
,因为 handleTap3
和 handleTap1
绑定的事件互斥,所以冒泡到 outer
时不会触发 handleTap1
。点击 middle view
会调用 handleTap2
和 handleTap1
。
事件捕获阶段绑定
小程序的触摸类事件支持捕获阶段。捕获阶段发生在冒泡事件之前,事件到达节点的顺序与冒泡阶段恰好相反。
对于 DOM
事件比较了解的小伙伴应该比较清楚,支持捕获阶段的事件触发流程如下: 可以通过 capture-bind
和 capture-catch
来在捕获阶段绑定事件,其中 capture-catch
会中断捕获阶段并取消冒泡阶段。
<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
会先后调用 handleTap2
、handleTap4
、handleTap3
、handleTap1
。
若将上例中的 capture-bind:touchstart="handleTap2"
改为 capture-catch:touchstart="handleTap2"
,将会仅触发 handleTap2
。
eg:
<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:
// index.wxml
<wxs module="tools" src="./tools.wxs"></wxs>
<view id="tapTest" data-hi="微信小程序" bindtap="{{tools.tapName}}"> Click me! </view>
// tools.wxs
function tapName(event, ownerInstance) {
console.log('tap 事件', JSON.stringify(event))
}
module.exports = {
tapName: tapName
}
结语
好啦,今天我们整体性的讲述了 小程序事件系统 相关的内容。相信读到这里的小伙伴已经对 小程序事件系统 有了比较清晰的了解,爱动手的小伙伴们快去动起来吧😁。
若有疑问,欢迎评论区。感谢阅读!愿你我共同进步,谢谢!!!