小程序可以調用宿主環境提供的微信客戶端的能力,這就使得小程序比普通網頁擁有更多的能力,組合這些能力可以完成一個體驗非常流暢的小程序。
小程序會運行在不同版本的宿主環境下,因此針對各個版本的宿主環境做程序上的兼容也是在所難免的,以便給不同環境下的的微信用戶提供可靠或者降級的服務。
[【官方文檔】](https://developers.weixin.qq.com/ebook?action=get_post_info&token=935589521&volumn=1&lang=zh_CN&book=miniprogram&docid=0004a2ef9b8f803b0086831c75140a)
[TOC]
## 小程序的啟動
1. **下載小程序代碼包**。微信客戶端在打開小程序之前,會把整個小程序的代碼包下載到本地。
2. **渲染小程序首頁**。微信客戶端通過`app.json` 的 `pages` 字段知道當前小程序的所有頁面路徑。通過小程序底層的一些機制,微信客戶端就把首頁的代碼裝載并渲染出首頁。
3. **執行onLaunch 回調**。小程序啟動之后,在`app.js` 定義的 `App` 實例的 `onLaunch` 回調會被執行。整個小程序只有一個 App 實例,是全部頁面共享的。
4. **界面生成**。微信客戶端根據頁面的`*.json` 配置文件生成一個界面。頂部的顏色和文字都可以在這個 json 文件里邊定義好。
5. **裝載頁面結構、樣式**。微信客戶端裝載頁面的`*.wxml`文件生成頁面結構,裝載頁面的`*.wxss`文件顯示頁面結構。
6. **渲染生成頁面**。微信客戶端裝載頁面的`*.js`文件,根據文件里的頁面構造器`Page `生成頁面。在生成頁面的時候,小程序框架會把`Page `里的 `data` 數據結合頁面的`*.wxml`文件一起渲染出最終的頁面。
7. **執行onLoad 回調**。在渲染完頁面之后,頁面實例(`Page `)就會收到一個 onLoad 的回調,可以在這個回調處理一些業務邏輯。
小程序啟動會有兩種情況
* **冷啟動**
用戶首次打開小程序或小程序被微信主動銷毀后再次打開的情況,此時小程序需要重新加載啟動。
* **熱啟動**
用戶已經打開過某小程序,然后在一定時間內再次打開該小程序,此時小程序無需重新啟動,只需將后臺態的小程序切換到前臺。
**更新機制**
小程序冷啟動時如果發現有新版本,將會異步下載新版本的代碼包,并同時用客戶端本地的包進行啟動,即新版本的小程序需要等下一次冷啟動才會應用上。 如果需要馬上應用最新版本,可以使用 `wx.getUpdateManager` API 進行處理。
**運行機制**
* 小程序沒有重啟的概念
* 當小程序進入后臺,微信客戶端會維持一段時間小程序的運行狀態,超過一定時間后小程序(目前是5分鐘)會被微信客戶端主動銷毀
* 當短時間內(5s)微信客戶端連續收到兩次以上系統內存告警,微信客戶端會進行小程序的銷毀
**再次打開邏輯**
用戶打開小程序的預期有以下兩類場景:
A. 打開首頁: 場景值有 1001(發現欄小程序主入口,“最近使用”列表), 1019(微信錢包), 1022(聊天頂部置頂小程序入口), 1023(安卓系統桌面圖標), 1038(從另一個小程序返回), 1056(音樂播放器菜單)
B. 打開小程序指定的某個頁面: 場景值為除 A 以外的其他
| 上一次的場景 | 當前打開的場景 | 效果 |
| --- | --- | --- |
| A | A | 保留原來的狀態 |
| B | A | 清空原來的頁面棧,打開首頁(相當于執行 wx.reLaunch 到首頁) |
| A 或 B | B | 清空原來的頁面棧,打開指定頁面(相當于執行 wx.reLaunch 到指定頁) |
## 2.1 渲染層和邏輯層
小程序的運行環境分成`渲染層`和`邏輯層`, 小程序的渲染層和邏輯層分離是經過很多考慮得出來的模型。
WXML 模板和 WXSS 樣式工作在渲染層,JS 腳本工作在邏輯層。
1. `渲染層`(WXML、WXSS文件)和數據相關。即:怎樣表現數據(`Show Data`)。
2. `邏輯層`(js文件)負責產生、處理數據。即:什么樣的數據(`What Data`)。
3. `邏輯層`(js文件)通過 Page 實例的 setData 方法傳遞數據到渲染層。即:怎么傳遞數據(`Send Data`)。
### 2.1.1 通信模型
小程序的渲染層和邏輯層分別由2個線程管理:
- 渲染層的界面使用了`WebView` 進行渲染;
- 邏輯層采用`JsCore`線程運行JS腳本。
一個小程序存在多個界面,所以渲染層存在多個WebView線程,這兩個線程的通信會經由微信客戶端(下文中也會采用Native來代指微信客戶端)做中轉,邏輯層發送網絡請求也經由Native轉發。
### 2.1.2 數據驅動
在開發UI界面過程中,通常界面視圖和變量狀態是相關聯的,可以通過`數據驅動`這種機制將狀態和視圖綁定在一起(狀態變更時,視圖也能自動變更),那我們就可以省去大量手動修改視圖的工作。
小程序的WXML結構實際上等價于一棵Dom樹,同時通過一個JS對象也可以來表達Dom樹的結構。
WXML可以先轉成JS對象,然后再渲染出真正的Dom樹。
>[info] HY:小程序數據驅動要點
> 1. JS對象
> 2. DOM樹
> 3. JS對象發生變化就會引起DOM樹的變化
### 2.1.3 雙線程下的界面渲染
小程序的邏輯層和渲染層是分開的兩個線程。
在渲染層,宿主環境會把WXML轉化成對應的JS對象,在邏輯層發生數據變更的時候,我們需要通過宿主環境提供的`setData`方法把數據從邏輯層傳遞到渲染層,再經過對比前后差異,把差異應用在原來的Dom樹上,渲染出正確的UI界面。
## 2.2 程序與頁面
從邏輯組成來說,一個小程序是由多個·`頁面`組成的`程序`。
而通常`程序`在啟動或者退出的時候存儲數據或者在“頁面”顯示或者隱藏的時候做一些邏輯處理。
### 2.2.1 程序
**1. 程序構造器`App()`**
宿主環境(客戶端)提供了`App()` 構造器用來注冊一個程序App,需要留意的是`App()` 構造器必須寫在項目根目錄的app.js里,App實例是單例對象,在其他JS腳本中可以使用宿主環境提供的 `getApp()` 來獲取程序實例。
:-: 表3-1 App構造器的參數
| 參數屬性 | 類型 | 描述|
| --- | --- | --- |
| onLaunch | Function | 當小程序初始化完成時,會觸發 onLaunch(全局只觸發一次)|
| onShow | Function | 當小程序啟動,或從后臺進入前臺顯示,會觸發 onShow |
| onHide | Function | 當小程序從前臺進入后臺,會觸發 onHide |
| onError | Function | 當小程序發生腳本錯誤,或者 API 調用失敗時,會觸發 onError 并帶上錯誤信息 |
| 其他字段 | 任意 | 可以添加任意的函數或數據到 Object 參數中,在App實例回調用 this 可以訪問 |
2. 程序的生命周期和打開場景
初次進入小程序的時候,微信客戶端初始化好宿主環境,同時從網絡下載或者從本地緩存中拿到小程序的代碼包,把它注入到宿主環境,初始化完畢后,微信客戶端就會給App實例派發onLaunch事件,App構造器參數所定義的`onLaunch`方法會被調用。
進入小程序之后,用戶可以點擊左上角的關閉,或者按手機設備的Home鍵離開小程序,此時小程序并沒有被直接銷毀,我們把這種情況稱為“小程序進入后臺狀態”,App構造器參數所定義的`onHide`方法會被調用。
當再次回到微信或者再次打開小程序時,微信客戶端會把“后臺”的小程序喚醒,我們把這種情況稱為“小程序進入前臺狀態”,App構造器參數所定義的`onShow`方法會被調用。
App的生命周期是由微信客戶端根據用戶操作主動觸發的。為了避免程序上的混亂,我們不應該從其他代碼里主動調用App實例的生命周期函數。
在微信客戶端中打開小程序有很多途徑:
* 從群聊會話里打開
* 從小程序列表中打開
* 通過微信掃一掃二維碼打開
* 從另外一個小程序打開當前小程序等
針對不同途徑的打開方式,小程序有時需要做不同的業務處理,所以微信客戶端會把打開方式帶給onLaunch和onShow的調用參數`options`。需要留意小程序的宿主環境在迭代更新過程會增加不少打開場景,因此要獲取最新的場景值說明請查看官方文檔:https://mp.weixin.qq.com/debug/wxadoc/dev/framework/app-service/app.html。
:-: 表3-2 onLaunch,onShow參數
| 字段 | 類型 | 描述 |
| --- |--- | ---|
| path | String | 打開小程序的頁面路徑 |
| query | Object | 打開小程序的頁面參數query |
| scene | Number | 打開小程序的場景值,詳細場景值請參考小程序官方文檔 |
| shareTicket | String | shareTicket,詳見小程序官方文檔 |
| referrerInfo | Object | 當場景為由從另一個小程序或公眾號或App打開時,返回此字段 |
| referrerInfo.appId | String | 來源小程序或公眾號或App的 appId,詳見下方說明 |
| referrerInfo.extraData | Object | 來源小程序傳過來的數據,scene=1037或1038時支持 |
:-: 表3-3 以下場景支持返回 referrerInfo.appId
| 場景值 | 場景 | appId信息含義 |
| --- |--- | ---|
| 1020 | 公眾號 profile | 頁相關小程序列表 返回來源公眾號 appId
| 1035 | 公眾號自定義菜單 | 返回來源公眾號 appId
| 1036 | App 分享消息卡片 | 返回來源應用 appId
| 1037 | 小程序打開小程序 | 返回來源小程序 appId
| 1038 | 從另一個小程序返回 | 返回來源小程序 appId
| 1043 | 公眾號模板消息 | 返回來源公眾號 appId
3. 小程序全局數據
小程序的JS腳本是運行在JsCore的線程里,小程序的每個頁面各自有一個WebView線程進行渲染,所以小程序切換頁面時,小程序邏輯層的JS腳本運行上下文依舊在同一個JsCore線程中。
小程序的App實例是單例的,因此不同頁面直接可以通過App實例下的屬性來共享數據。
>[danger] App構造器可以傳遞其他參數作為全局屬性以達到全局共享數據的目的。
>[danger] 由于所有頁面的腳本邏輯都跑在同一個JsCore線程,頁面使用setTimeout或者setInterval的定時器,然后跳轉到其他頁面時,這些定時器并沒有被清除,需要開發者自己在頁面離開的時候進行清理。
### 2.2.2 頁面
一個小程序可以有很多頁面,每個頁面承載不同的功能,頁面之間可以互相跳轉。
1. 頁面的文件構成和路徑
一個頁面是分三部分組成:
* 界面:`WXML`文件和`WXSS`文件描述
* 配置:由`JSON`文件進行描述
* 邏輯:`JS`腳本文件負責
>[danger] 一個頁面的文件需要放置在同一個目錄下,其中WXML文件和JS文件是必須存在的,JSON和WXSS文件是可選的。
>[danger] 頁面路徑需要在小程序代碼根目錄app.json中的pages字段聲明,否則這個頁面不會被注冊到宿主環境中。
**2. 頁面構造器`Page()`**
宿主環境提供了` Page()` 構造器用來注冊一個小程序頁面,Page()在頁面腳本page.js中調用,Page構造器接受一個Object參數,參數說明如表3-4所示。
* 初始數據: `data`屬性是當前頁面WXML模板中可以用來做數據綁定的初始數據;
* 生命周期函數:`onLoad / onReady / onShow / onHide /onUnload` 5個回調是Page實例的生命周期函數;
* 用戶行為: `onPullDownRefresh / onReachBottom / onShareAppMessage / onPageScroll` 4個回調是頁面的用戶行為。
:-: 表3-4 Page構造器的參數
| 參數屬性 | 類型 | 描述 |
| --- |--- | --- |
| data | Object | 頁面的初始數據 |
| onLoad | Function | 生命周期函數--監聽頁面加載,觸發時機早于onShow和onReady |
| onReady | Function | 生命周期函數--監聽頁面初次渲染完成 |
| onShow | Function | 生命周期函數--監聽頁面顯示,觸發事件早于onReady |
| onHide | Function | 生命周期函數--監聽頁面隱藏 |
| onUnload | Function | 生命周期函數--監聽頁面卸載 |
| onPullDownRefresh | Function | 頁面相關事件處理函數--監聽用戶下拉動作 |
| onReachBottom | Function | 頁面上拉觸底事件的處理函數 |
| onShareAppMessage | Function | 用戶點擊右上角轉發 |
| onPageScroll | Function | 頁面滾動觸發事件的處理函數 |
| 其他 | Any | 可以添加任意的函數或數據,在Page實例的其他函數中用 this 可以訪問 |
3. 頁面的生命周期和打開參數
頁面初次加載的時候,微信客戶端就會給Page實例派發onLoad事件,Page構造器參數所定義的`onLoad`方法會被調用,onLoad在頁面沒被銷毀之前只會觸發1次,在onLoad的回調中,可以獲取當前頁面所調用的打開參數option。
頁面顯示之后,Page構造器參數所定義的`onShow`方法會被調用,一般從別的頁面返回到當前頁面時,當前頁的onShow方法都會被調用。
在頁面初次渲染完成時,Page構造器參數所定義的`onReady`方法會被調用,onReady在頁面沒被銷毀前只會觸發1次,onReady觸發時,表示頁面已經準備妥當,在邏輯層就可以和視圖層進行交互了。
以上三個事件觸發的時機是onLoad早于 onShow,onShow早于onReady。
頁面不可見時,Page構造器參數所定義的`onHide`方法會被調用,這種情況會在使用`wx.naviagteTo`切換到其他頁面、底部tab切換時觸發。
當前頁面使用wx.redirectTo或wx.navigateBack返回到其他頁時,當前頁面會被微信客戶端銷毀回收,此時Page構造器參數所定義的`onUnload`方法會被調用。
上述5個Page的生命周期函數/方法是由微信客戶端根據用戶操作主動觸發的。為了避免程序上的混亂,我們不應該在其他代碼中主動調用Page實例的生命周期函數。
* 頁面的打開參數
使用場景舉例:購物商城的小程序,一個商品列表頁和商品詳情頁,點擊商品列表頁的商品就可以跳轉到該商品的詳情頁。
當然我們不可能為每個商品單獨去實現它的詳情頁。我們只需要實現一個商品詳情頁的pages/detail/detail.(代表WXML/WXSS/JS/JSON文件)即可,在列表頁打開商品詳情頁時把商品的id傳遞過來,詳情頁通過剛剛說的onLoad回調的參數option就可以拿到商品id,從而繪制出對應的商品
小程序把頁面的打開路徑定義成頁面URL,其組成格式和網頁的URL類似,在頁面路徑后使用英文 ? 分隔path和query部分。
* query部分:多個參數使用 `&` 進行分隔,參數的名字和值使用 key=value 的形式聲明。
在頁面Page構造器里onLoad的option可以拿到當前頁面的打開參數,其類型是一個Object,其鍵值對與頁面URL上query鍵值對一一對應。
和網頁URL一樣,頁面URL上的value如果涉及特殊字符(例如:`&`字符、`?`字符、`中文`字符等,詳情參考URI的RFC3986說明 ),需要采用UrlEncode后再拼接到頁面URL上。
4. 頁面的數據
小程序的頁面結構由WXML進行描述,WXML可以通過數據綁定的語法綁定從邏輯層傳遞過來的數據字段(頁面Page構造器的data字段,data參數是頁面第一次渲染時從邏輯層傳遞到渲染層的數據)。
宿主環境所提供的Page實例的原型中有`setData`函數,我們可以在Page實例下的方法調用`this.setData`把數據傳遞給渲染層,從而達到更新界面的目的。
由于小程序的渲染層和邏輯層分別在兩個線程中運行,所以setData傳遞數據實際是一個異步的過程,所以setData的第二個參數是一個callback回調,在這次setData對界面渲染完畢后觸發。
setData其一般調用格式是 setData(data, callback),其中data是由多個key: value構成的Object對象。
5. 頁面的用戶行為
小程序宿主環境提供了四個和頁面相關的用戶行為回調:
* 下拉刷新 `onPullDownRefresh`
* 上拉觸底 `onReachBottom`
* 頁面滾動` onPageScroll`
* 用戶轉發 `onShareAppMessage`
6. 頁面跳轉和路由
一個小程序擁有多個頁面,我們可以通過`wx.navigateTo`推入一個新的頁面。在首頁使用2次wx.navigateTo后,頁面層級會有三層,我們把這樣的一個頁面層級稱為`頁面棧`。
頁面棧描述:\[ pageA, pageB, pageC ],其中pageA在最底下,pageC在最頂上,也就是用戶所看到的界面。小程序宿主環境限制了這個頁面棧的最大層級為10層 ,也就是當頁面棧到達10層之后就沒有辦法再推入新的頁面了。
和導航相關的API:
* `wx.navigateTo({ url: 'pageD' })`: 可以往當前頁面棧多推入一個 pageD,只能打開非TabBar頁面。
* `wx.navigateBack()` 可以退出當前頁面棧的最頂上頁面。
* `wx.redirectTo({ url: 'pageE' })` 是替換當前頁變成pageE,當頁面棧到達10層沒法再新增的時候,往往就是使用redirectTo這個API進行頁面跳轉。只能打開非TabBar頁面。
* `wx.switchTab({ url: 'pageF' })`,此時原來的頁面棧會被清空(除了已經聲明為Tabbar頁的pageA外其他頁面會被銷毀),然后會切到pageF所在的tab頁面,頁面棧變成 \[ pageF ],此時點擊Tab1切回到pageA時,pageA不會再觸發onLoad,因為pageA沒有被銷毀。
* `wx. reLaunch({ url: 'pageH' })` 重啟小程序,并且打開pageH,此時頁面棧為 \[ pageH ]。
>[danger] `wx.navigateTo`和`wx.redirectTo`只能打開非TabBar頁面,
>`wx.switchTab`只能打開Tabbar頁面。
小程序提供了原生的`Tabbar`支持,我們可以在`app.json`聲明tabBar字段來定義Tabbar頁(注:更多詳細參數見Tabbar官方文檔 )。
:-: 表3-5頁面路由觸發方式及頁面生命周期函數的對應關系。
| 路由方式 | 觸發時機 | 路由前頁面生命周期 | 路由后頁面生命周期 |
| --- | --- | --- | --- |
| 初始化 | 小程序打開的第一個頁面 | | onLoad, onShow |
| 打開新頁面 | 調用 | API wx.navigateTo | onHide | onLoad, onShow |
| 頁面重定向 | 調用 | API wx.redirectTo | onUnload | onLoad, onShow |
| 頁面返回 | 調用 | API wx.navigateBack | onUnload | onShow |
| Tab | 切換 調用 | API wx.switchTab | 請參考表3-6 | 請參考表3-6 |
| 重啟動 | 調用 | API wx.reLaunch | onUnload | onLoad, onShow |
:-: 表3-6 頁面路由觸發方式及頁面生命周期函數的對應關系
| 當前頁面 | 路由后頁面 | 觸發的生命周期(按順序)|
| --- | --- | --- |
| A | A | 無 |
| A | B | A.onHide(), B.onLoad(), B.onShow() |
| A | B(再次打開) | A.onHide(), B.onShow() |
| C | A | C.onUnload(), A.onShow() |
| C | B | C.onUnload(), B.onLoad(), B.onShow() |
| D | B | D.onUnload(), C.onUnload(), B.onLoad(), B.onShow() |
| D(從轉發進入) | A | D.onUnload(), A.onLoad(), A.onShow() |
| D(從轉發進入) | B | D.onUnload(), B.onLoad(), B.onShow() |
Tab 切換對應的生命周期(以 A、B 頁面為 Tabbar 頁面,C 是從 A 頁面打開的頁面,D 頁面是從 C 頁面打開的頁面為例)如表3-6所示,注意Tabbar頁面初始化之后不會被銷毀。
## 2.3 組件
一個小程序頁面可以分解成多個部分組成,組件就是小程序頁面的基本組成單元。小程序的宿主環境提供了一系列基礎組件。
組件說明 https://mp.weixin.qq.com/debug/wxadoc/dev/component/。
組件是在WXML模板文件聲明中使用的,WXML的語法和HTML語法相似,小程序使用標簽名來引用一個組件,通常包含開始標簽和結束標簽,該標簽的屬性用來描述該組件。
>[danger]所有組件名和屬性都是小寫,多個單詞會以英文橫杠 "-" 進行連接。
所有組件都擁有表3-7列舉的屬性,主要涉及樣式和事件綁定。
:-: 表3-7 組件共有屬性
| 屬性名 | 類型 | 描述 | 其他說明 |
| --- | --- | --- | --- |
| id | String | 組件的唯一標示 | 保持整個頁面唯一 |
| class | String | 組件的樣式類 | 在對應的WXSS中定義的樣式類 |
| style | String | 組件的內聯樣式 | 可以通過數據綁定進行動態設置的內聯樣式|
| hidden | Boolean | 組件是否顯示 | 所有組件默認顯示|
| data-* | Any | 自定義屬性 | 組件上觸發的事件時,會發送給事件處理函數 |
| bind /catch | EventHandler | 事件 | 詳情見`2.5節 事件` |
組件都擁有各自自定義的屬性,可以對該組件的功能或者樣式進行修飾。
## 2.4 API
宿主環境提供了豐富的API,可以很方便調用微信提供的能力。幾乎所有小程序的API都掛載在wx對象底下(除了Page/App等特殊的構造器)。
小程序提供的API按照功能主要分為幾大類:網絡、媒體、文件、數據緩存、位置、設備、界面、界面節點信息還有一些特殊的開放接口,API一般調用的約定:
1. wx.on* 開頭的 API 是監聽某個事件發生的API接口,接受一個 Callback 函數作為參數。當該事件觸發時,會調用 Callback 函數。
2. 如未特殊約定,多數 API 接口為異步接口 ,都接受一個Object作為參數。
3. API的Object參數一般由success、fail、complete三個回調來接收接口調用結果,示例代碼如代碼清單3-17所示,詳細說明如表3-9所示。
4. wx.get* 開頭的API是獲取宿主環境數據的接口。
5. wx.set* 開頭的API是寫入數據到宿主環境的接口。
:-: 表3-9 API接口回調說明
| 參數名字 | 類型 | 必填 | 描述 |
| --- | --- | --- | --- |
| success | Function | 否 | 接口調用成功的回調函數|
| fail | Function | 否 | 接口調用失敗的回調函數|
| complete | Function | 否 | 接口調用結束的回調函數(調用成功、失敗都會執行)|
>[info] * API調用大多都是異步的,
>* 有部分API會拉起微信的原生界面,此時會觸發Page的`onHide`方法,當用戶從原生界面返回到小程序時,會觸發Page的`onShow`方法。
API的數量非常多,而且隨著宿主環境的迭代更新會持續新增API,了解一般調用API的技巧,再通過[【官方API文檔】 ](https://mp.weixin.qq.com/debug/wxadoc/dev/api/)了解到對應的API參數細節即可。
## 2.5 事件
在小程序里,把“用戶在渲染層的行為反饋”以及“組件的部分狀態反饋”抽象為渲染層傳遞給邏輯層的“事件”。
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 | 觸摸事件,當前變化的觸摸點信息的數組|
`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軸|
### 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`的含義分別代表事件的冒泡階段和捕獲階段
>bind事件綁定不會阻止冒泡事件向上冒泡,catch事件綁定可以阻止冒泡事件向上冒泡。
注意,除表3-10列舉的事件類型之外的其他組件自定義事件,如無特殊聲明都是非冒泡事件,如\<form/>的submit事件,\<input/>的input事件,\<scroll-view/>的scroll事件。
## 2.6 兼容
1. **使用 `wx.getSystemInfo` 或者 `wx.getSystemInfoSync`** API來獲取手機品牌、操作系統版本號、微信版本號以及小程序基礎庫版本號等,通過這個信息,我們可以針對不同平臺做差異化的服務。
2. **判斷API是否存在**來做程序上的兼容。
3. **使用`wx.canIUse`** API,用于判斷接口或者組件在當前宿主環境是否可用,其參數格式為: `${API}.${method}.${param}.${options}或者${component}.${attribute}.${option}`
各個段的含義如下:
* ${API} 代表 API 名字
* ${method} 代表調用方式,有效值為return, success, object, callback
* ${param} 代表參數或者返回值
* ${options} 代表參數的可選值
* ${component} 代表組件名字
* ${attribute} 代表組件屬性
* ${option} 代表組件屬性的可選值
我們可以選擇合適的判斷方法來做小程序的向前兼容,以保證我們的小程序在舊版本的微信客戶端也能工作正常。
在不得已的情況下(小程序強依賴某個新的API或者組件時),還可以通過在小程序管理后臺設置“基礎庫最低版本設置”來達到不向前兼容的目的。
例如你選擇設置你的小程序只支持1.5.0版本以上的宿主環境,那么當運行著1.4.0版本宿主環境的微信用戶打開你的小程序的時候,微信客戶端會顯示當前小程序不可用,并且提示用戶應該去升級微信客戶端。
- 微信
- 小程序
- 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列表