小程序事件绑定及传参
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.elementType
data-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)