[TOC]
## 2.5 事件
[【官方文档1】](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html)
[【官方文档2】](https://developers.weixin.qq.com/ebook?action=get_post_info&token=935589521&volumn=1&lang=zh_CN&book=miniprogram&docid=000846df9a03909b0086a50025180a)
在小程序里,把这种“用户在渲染层的行为反馈”以及“组件的部分状态反馈”抽象为渲染层传递给逻辑层的“事件”,如图3-7所示。
:-: ![渲染层产生用户交互事件传递给逻辑层](https://box.kancloud.cn/ef0d7d054006785cd71312ebd99130fb_750x521.png)
:-: 图3-7 渲染层产生用户交互事件传递给逻辑层
代码清单3-18 事件处理示例
~~~
<!-- page.wxml -->
<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
// page.js
Page({
tapName: function(event) {
console.log(event)
}
})
~~~
1. 组件绑定事件处理函数。wxml文件中,事件是通过`bindtap`这个属性绑定在组件上的。
2. 定义事件处理函数。js文件中,在当前页面的Page构造器中定义对应的事件处理函数`tapName`;
3. 触发事件。当用户点击该view区域时,达到触发条件生成事件`tap`,该事件处理函数tapName会被执行,同时还会收到一个事件对象event。
### 2.5.1 事件类型和事件对象
组件的事件可以参考其参数说明,详情见[官方文档](https://mp.weixin.qq.com/debug/wxadoc/dev/component/ )
常见的用户事件类型如表3-10所示。
:-: 表3-10 常见的冒泡事件类型
| 类型 | 触发条件 |
| --- | --- |
| touchstart | 手指触摸动作开始|
| touchmove | 手指触摸后移动|
| touchcancel | 手指触摸动作被打断,如来电提醒,弹窗|
| touchend | 手指触摸动作结束|
| tap | 手指触摸后马上离开|
| longpress | 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发|
| longtap | 手指触摸后,超过350ms再离开(推荐使用longpress事件代替)|
| transitionend | 会在 WXSS transition 或 wx.createAnimation 动画结束后触发|
| animationstart | 会在一个 WXSS animation 动画开始时触发|
| animationiteration | 会在一个 WXSS animation 一次迭代结束时触发|
| animationend | 会在一个 WXSS animation 动画完成时触发|
当事件回调触发的时候,会收到一个事件对象,对象的详细属性如下表所示。
:-: 表3-11 事件对象属性
| 属性 | 类型 | 说明|
| --- | ---| ---|
| type | String | 事件类型|
| timeStamp | Integer | 页面打开到触发事件所经过的毫秒数|
| target | Object | 触发事件的组件的一些属性值集合|
| currentTarget | Object | 当前组件的一些属性值集合|
| detail | Object | 额外的信息|
| touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组|
| changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组|
这里需要注意的是`target`和`currentTarget`的区别,currentTarget为当前事件所绑定的组件,而target则是触发该事件的源头组件。
:-: 表3-12 target和currentTarget事件对象属性
| 属性 | 类型 | 说明|
| --- | ---| ---|
| id | String | 当前组件的id|
| tagName | String | 当前组件的类型|
| dataset | Object | 当前组件上由data-开头的自定义属性组成的集合|
:-: 表3-13 touch和changedTouches对象属性
| 属性 | 类型 | 说明|
| --- | ---| ---|
| identifier | Number | 触摸点的标识符|
| pageX, pageY | Number | 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴|
| clientX, clientY | Number | 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴|
代码清单3-19 事件对象示例
~~~HTML
<!-- page.wxml -->
<view id="outer" catchtap="handleTap">
<view id="inner">点击我</view>
</view>
~~~
~~~JavaScript
// page.js
Page({
handleTap: function(evt) {
// 当点击inner节点时
// evt.target 是inner view组件
// evt.currentTarget 是绑定了handleTap的outer view组件
// evt.type == “tap”
// evt.timeStamp == 1542
// evt.detail == {x: 270, y: 63}
// evt.touches == [{identifier: 0, pageX: 270, pageY: 63, clientX: 270, clientY: 63}]
// evt.changedTouches == [{identifier: 0, pageX: 270, pageY: 63, clientX: 270, clientY: 63}]
}
})
~~~
### 2.5.2 事件绑定与冒泡捕获
事件绑定的写法和组件属性一致,以`key="value"`的形式,其中:
1. **`key`以bind或者catch开头,然后跟上事件的类型**,如`bindtap`、`catchtouchstart`。
自基础库版本1.5.0起,bind和catch后可以紧跟一个冒号,其含义不变,如`bind:tap`、`catch:touchstart`。同时bind和catch前还可以加上`capture-`来表示捕获阶段。
2. **`value`是一个字符串**,需要在对应的页面Page构造器中定义同名的函数,否则触发事件时在控制台会有报错信息。
3. `bind`和`capture-bind`的含义分别代表事件的冒泡阶段和捕获阶段,其触发的顺序如图3-8所示。
:-: ![事件捕获和冒泡触发时序](https://box.kancloud.cn/767707139670f8409eb9d62c13a7c7a1_681x573.png)
:-: 图3-8 事件捕获和冒泡触发时序
以下示例中,点击 inner view 会先后调用handleTap1、handleTap2、handleTap3、handleTap4。
代码清单3-20 使用capture-前缀阻止事件的冒泡和捕获
~~~HTML
<view id="outer" bind:tap="handleTap4" capture-bind:tap="handleTap1">
outer view
<view id="inner" bind:tap="handleTap3" capture-bind:tap="handleTap2">
inner view
</view>
</view>
~~~
>bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。
如果将以上代码的capture-bind:tap="handleTap1"改成capture-catch:tap="handleTap1",点击inner view只会触发handleTap1(catch事件阻止了tap事件冒泡)。
代码清单3-21 事件的冒泡和捕获
~~~HTML
<view id="outer" bind:tap="handleTap4" capture-catch:tap="handleTap1">
outer view
<view id="inner" bind:tap="handleTap3" capture-bind:tap="handleTap2">
inner view
</view>
</view>
~~~
注意,除表3-10列举的事件类型之外的其他组件自定义事件,如无特殊声明都是非冒泡事件,如\<form/>的submit事件,\<input/>的input事件,\<scroll-view/>的scroll事件。
- 微信
- 小程序
- 1. 代码组成
- 1.1 JSON配置--'*.json'文件
- 1.2 WXML模板--'*.wxml'文件
- 1.3 WXSS样式--'*.wxss'文件
- 1.4 JavaScript脚本--'*.js'文件
- 2. 客户端运行
- 2.1 逻辑层和渲染层
- 2.1.1 逻辑层--App Service
- 2.1.2 渲染层/视图层--View
- 2.1.3 通信模型
- 2.1.4 数据驱动
- 2.1.5 双线程下的界面渲染
- 2.2 程序与页面
- 2.3 组件
- 2.4 API
- 2.5 事件
- 2.6 兼容
- 3. 应用设计
- 3.1 Flex布局
- 3.2 界面常见的交互反馈
- 3.3 发起HTTPS网络通信--wx.request
- 3.4 微信登录
- 3.5 本地数据缓存
- 3.6 设备能力
- 4. 小程序的协同工作和发布
- 4.1 协同工作
- 4.2 用户体验审视
- 4.3 发布
- 4.4 运营
- 5. 底层框架
- 5.1 双线程模型
- 5.2 组件系统--Exparser框架
- 5.3 原生组件
- 5.4 小程序与客户端通信原理
- 6. 运行和性能优化
- 6.1 启动--代码加载
- 6.2 页面准备
- 6.3 数据通信
- 6.4 视图层渲染
- 6.5 原生组件通信
- 7. 小程序基础库的更新迭代
- 8. 微信开发者工具
- 腾讯云支持
- wafer
- Wafer2 快速开发 Demo - PHP
- WXAPI
- api列表