# 事件
事件将用户在渲染层的操作,反馈到逻辑层,触发对应的事件处理函数,进而响应用户的交互。事件对象可以传递额外的数据,如 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 代表距离文档左上角的距离。
在线客服