微信小程序事件绑定及传参
1. 小程序事件分类
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 事件(详见各个组件)
2. 事件绑定
2.1 普通事件绑定
<view bindtap="handleTap">
Click here!
</view>
事件绑定函数可以是一个数据绑定,如:
<view bindtap="{{ handlerName }}">
Click here!
</view>
此时,页面的 this.data.handlerName 必须是一个字符串,指定事件处理函数名;如果它是个空字符串,则绑定会失效(可以利用这个特性来暂时禁用一些事件)
2.2 绑定并阻止冒泡
catch 也可绑定事件,与 bind 的区别在于 catch 会阻止事件向上冒泡。
<view bindtap="handleTap1">
view1
<view catchtap="handleTap2">
view2
<view bindtap="handleTap3">
view3
</view>
</view>
</view>
上面点击事件中:
- 点击 view1 调用
handleTap1; - 点击 view2 调用
handleTap2,catch 阻止了事件冒泡,因此不触发handleTap1; - 点击 view3 先后调用
handleTap3和handleTap2。
2.3 互斥事件绑定
mut-bind 可以用来绑定互斥事件,一个 mut-bind 触发后,如果事件冒泡到其他节点上,其他节点上的 mut-bind 绑定函数不会被触发。
<view mut-bind:tap="handleTap1">
view1
<view bindtap="handleTap2">
view2
<view mut-bind:tap="handleTap3">
view3
</view>
</view>
</view>
上面点击事件中:
- 点击 view1 调用
handleTap1; - 点击 view2 先后调用
handleTap2和handleTap1; - 点击 view3 先后调用
handleTap3和handleTap2,由于与 view1 的mut-bind互斥,因此不触发handleTap1。
2.4 事件的捕获阶段
触摸类事件支持捕获阶段,捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段相反。
需要在捕获阶段监听事件时,可以采用 capture-bind、capture-catch 关键字,后者将中断捕获阶段和取消冒泡阶段。
<view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2">
view1
<view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
view2
</view>
</view>
上面点击 view2 会先后调用 handleTap2 > handleTap4 > handleTap3 > handleTap1
如果将第一个 capture-bind 改为 capture-catch,例如:
<view id="outer" bind:touchstart="handleTap1" capture-catch:touchstart="handleTap2">
view1
<view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
view2
</view>
</view>
则点击 view2 将只触发 handleTap2
3. 事件对象
当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象,属性如下:
type
String 事件类型
timeStamp
Integer 事件生成时的时间(毫秒)
target & currentTarget
target
Object 触发事件的源组件
| 属性 | 类型 | 说明 |
|---|---|---|
| id | String | 事件源组件的 id |
| dataset | Object | 事件源组件上由 data- 开头的自定义属性组成的集合 |
currentTarget
Object 事件绑定的当前组件
| 属性 | 类型 | 说明 |
|---|---|---|
| id | String | 当前组件的 id |
| dataset | Object | 当前组件上由 data- 开头的自定义属性组成的集合 |
举个例子:
// index.wxml
<view id="view1" bindtap="handleTap1">
view1
<view id="view2" bindtap="handleTap2">
view2
</view>
</view>
// index.js
handleTap1(e) {
console.log(e);
},
handleTap2(e) {
console.log(e);
},
点击 view2 时,先后触发 handleTap2 和 handleTap1,其中:
触发的 handleTap2 打印结果:

触发的 handleTap1 打印结果:

dataset
组件节点中附加的自定义数据,可用于节点的事件传参。
在 WXML 中,这些自定义数据以 data- 开头,多个单词由连字符 - 连接,其中连字符会转驼峰,驼峰会转小写。如:
data-element-type,最终呈现为event.currentTarget.dataset.elementTypedata-elementType,最终呈现为event.currentTarget.dataset.elementtype
示例:
// index.wxml
<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view>
// index.js
Page({
bindViewTap:function(event){
event.currentTarget.dataset.alphaBeta === 1 // - 会转为驼峰写法
event.currentTarget.dataset.alphabeta === 2 // 大写会转为小写
}
})
mark
Object 事件标记数据,节点上由 mark: 开头的自定义属性组成的集合(类似于 dataset )
当事件触发时,事件冒泡路径上所有的 mark 会被合并,并返回给事件回调函数(即使事件不是冒泡事件,也会 mark)
示例:
// index.wxml
<view mark:myMark="last" bindtap="handleTap1">
<button mark:anotherMark="leaf" bindtap="handleTap2">按钮</button>
</view>
// index.js
handleTap1(e) {
console.log(e);
},
handleTap2(e) {
console.log(e);
},
点击按钮时,先后触发 handleTap2 和 handleTap1,其中:
触发的 handleTap2 打印结果:

触发的 handleTap1 打印结果:

mark 和 dataset 很相似,主要区别在于: mark 会包含从触发事件的节点到根节点上所有的 mark: 属性值;而 dataset 仅包含一个节点的 data- 属性值。另外:
- 如果存在同名的
mark,父节点的mark会被子节点覆盖; - 在自定义组件中接收事件时,
mark不包含自定义组件外的节点的mark - 不同于
dataset,节点的mark不会做连字符和驼峰大小写转换。
detail
Object 自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见组件定义中各个事件的定义。
点击事件的 detail 带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离。
touches
Array 触摸事件属性,表示当前停留在屏幕中的触摸点信息的数组:
Touch 对象
| 属性 | 类型 | 说明 |
|---|---|---|
| identifier | Number | 触摸点的标识符 |
| pageX, pageY | Number | 距离文档左上角的距离,文档的左上角为原点 ,横向为 X 轴,纵向为 Y 轴 |
| clientX, clientY | Number | 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为 X 轴,纵向为 Y 轴 |
CanvasTouch 对象
| 属性 | 类型 | 说明 |
|---|---|---|
| identifier | Number | 触摸点的标识符 |
| x, y | Number | 距离 Canvas 左上角的距离,Canvas 的左上角为原点 ,横向为 X 轴,纵向为 Y 轴 |
changedTouches
Array 触摸事件属性,数据格式同 touches,表示当前变化的触摸点信息的数组,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel)