# 事件
事件将用户在渲染层的操作,反馈到逻辑层,触发对应的事件处理函数,进而响应用户的交互。事件对象可以传递额外的数据,如 id, dataset, touches。
# 事件使用示例
- 在组件中绑定一个事件处理函数,如
bindtap="handleTap"
<view id="testView" data-hi="QuickApp" bindtap="handleTap">点击</view>
- 在相应的 Page 定义中编写事件处理函数,参数是事件对象 event。
Page({
handleTap: function(event) {
console.log(event)
}
})
2
3
4
5
- 打印的 event 结构如下:
{
"type": "tap",
"timeStamp": 868,
"target": {
"id": "testView",
"dataset": {
"hi": "QuickApp"
}
},
"currentTarget": {
"id": "testView",
"dataset": {
"hi": "QuickApp"
}
},
"detail": {
"x": 59,
"y": 36
},
"touches": [
{
"identifier": 0,
"pageX": 59,
"pageY": 36,
"clientX": 59,
"clientY": 36
}
],
"changedTouches": [
{
"identifier": 0,
"pageX": 59,
"pageY": 36,
"clientX": 59,
"clientY": 36
}
]
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 使用 QJS 函数响应事件
使用 QJS 函数处理事件这种情况下,QJS 函数接受 2 个参数,第一个是 event 对象,event 除了有上面基本的属性外,还具有一个 instance 属性;第二个参数是 ownerInstance,和event.instance 一样是一个 ComponentDescriptor 对象。
代码示例:
- 在 qxml 中绑定 QJS 函数。
<qjs module="qjs" src="./test.qjs"></qjs>
<view id="testView" data-hi="QuickApp" bindtap="{{qjs.handleTap}}"> Click Button </view>
2
注意:绑定的 QJS 函数必须用{{}}括起来
- test.qjs 文件实现 handleTap 函数
function handleTap(event, ownerInstance) {
console.log('tap button', JSON.stringify(event))
}
module.exports = {
handleTap: handleTap
}
2
3
4
5
6
ComponentDescriptor 对象拥有一些方法,可以设置组件的样式等。 更多详情请参考文档。
# 事件详解
# 事件分类
快应用渲染层中事件分为冒泡事件和非冒泡事件:
- 冒泡事件是指当一个组件上的事件被触发后,该事件会向父节点传递。
- 非冒泡事件是指当一个组件上的事件被触发后,该事件不会向父节点传递。
冒泡事件列表:
| 类型 | 触发条件 |
|---|---|
| touchstart | 手指触摸动作开始 |
| touchmove | 手指触摸后移动 |
| touchcancel | 手指触摸动作被打断,如来电提醒,弹窗 |
| touchend | 手指触摸动作结束 |
| tap | 手指触摸后马上离开 |
| longpress | 手指触摸后,超过 350ms 再离开,如果指定了事件回调函数并触发了这个事件,tap 事件将不被触发 |
| longtap | 手指触摸后,超过 350ms 再离开(推荐使用 longpress 事件代替) |
| transitionend | 会在 transition 或 qa.createAnimation 动画结束后触发 |
| animationstart | 会在一个 animation 动画开始时触发 |
| animationiteration | 会在一个 animation 一次迭代结束时触发 |
| animationend | 会在一个 animation 动画完成时触发 |
注:其他事件如无特殊声明都是非冒泡事件,如 form 的submit事件,input 的input事件,scroll-view 的scroll事件
# 事件绑定和冒泡
事件绑定的写法和组件的属性相同。
- key 以
bind或catch开头,后面拼接事件的类型,如bindtap、catchtouchstart。bind和catch后也可以紧跟一个冒号,如bind:tap、catch:touchstart,作用一致。 - value 是一个字符串,需要在对应的 Page 中定义同名的函数。否则当触发事件的时候会报错。
- bind 与 catch 的区别:bind 事件绑定不会阻止冒泡事件向上冒泡,而 catch 则会。
代码示例:
<view id="view1" bindtap="handleTap1">
view1
<view id="view2" catchtap="handleTap2">
view2
<view id="view3" bindtap="handleTap3">
view3
</view>
</view>
</view>
2
3
4
5
6
7
8
9
执行效果:
- 点击 view3 会先后调用
handleTap3和handleTap2(这是因为 tap 事件会冒泡到 view2,而 view2 阻止了 tap 事件冒泡,不再向父节点 view1 传递) - 点击 view2 只触发
handleTap2 - 点击 view1 只触发
handleTap1
# 事件的捕获阶段
捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段相反。捕获阶段监听事件,可以采用capture-bind、capture-catch关键字,后者将中断捕获阶段和取消冒泡阶段。
示例代码:
<view id="view1" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2">
view1
<view id="view3" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
view3
</view>
</view>
2
3
4
5
6
执行效果:
- 点击 view3 会先后调用
handleTap2、handleTap4、handleTap3、handleTap1
示例代码:(上面代码中的第一个capture-bind改为capture-catch)
<view id="view1" bind:touchstart="handleTap1" capture-catch:touchstart="handleTap2">
view1
<view id="view3" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
view3
</view>
</view>
2
3
4
5
6
执行效果:
- 点击 view3 只触发
handleTap2
# 事件对象
当组件触发事件时,逻辑层绑定的处理函数会收到一个事件对象。
| 属性 | 类型 | 说明 |
|---|---|---|
| type | String | 事件类型 |
| timeStamp | Integer | 事件生成时的时间戳 |
| target | Object | 触发事件的组件的属性值集合 |
| currentTarget | Object | 当前组件的属性值集合 |
| detail | Object | 自定义事件对象额外的信息 |
| touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 |
| changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
各属性详细信息如下。
# target
触发事件的源组件。
| 属性 | 类型 | 说明 |
|---|---|---|
| id | String | 触发事件的组件 id |
| dataset | Object | 触发事件的组件上由 data- 开头的自定义属性组成的集合 |
# currentTarget
事件绑定的当前组件。
| 属性 | 类型 | 说明 |
|---|---|---|
| id | String | 当前组件的 id |
| dataset | Object | 当前组件上由data-开头的自定义属性组成的集合 |
说明: target 和 currentTarget 可以参考上例中,点击 view3 时,handleTap3 收到的事件对象 target 和 currentTarget 都是 view3,而 handleTap2 收到的事件对象 target 就是 view3,currentTarget 就是 view2。
# dataset
在组件节点中可以定义一些自定义数据,触发事件时会传入回调中处理。
在 QXML 中,这些自定义数据以 data- 开头,多个单词由连字符 - 连接。这种写法中,连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符。如:
data-custom-value,最终会呈现为event.currentTarget.dataset.customValue;data-customValue,最终会呈现为event.currentTarget.dataset.customvalue。
# touches
touches 是一个数组,每个元素为一个 Touch 对象。 表示当前停留在屏幕上的触摸点。另外 canvas 触摸事件中携带的 touches 是 CanvasTouch 数组。
# Touch 对象
| 属性 | 类型 | 说明 |
|---|---|---|
| identifier | Number | 触摸点的标识符 |
| pageX, pageY | Number | 距离文档左上角的距离,文档的左上角为原点 ,横向为 X 轴,纵向为 Y 轴 |
| clientX, clientY | Number | 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为 X 轴,纵向为 Y 轴 |
# CanvasTouch 对象
| 属性 | 类型 | 说明 |
|---|---|---|
| identifier | Number | 触摸点的标识符 |
| x, y | Number | 距离 Canvas 左上角的距离,Canvas 的左上角为原点 ,横向为 X 轴,纵向为 Y 轴 |
# changedTouches
changedTouches 数据格式同 touches。 表示有变化的触摸点,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel)。
# detail
自定义事件数据,详见组件定义中各个事件的定义。
点击事件的detail 带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离。
在线客服