[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所示。
:-: 
:-: 圖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所示。
:-: 
:-: 圖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列表