小程序可以调用宿主环境提供的微信客户端的能力,这就使得小程序比普通网页拥有更多的能力,组合这些能力可以完成一个体验非常流畅的小程序。
小程序会运行在不同版本的宿主环境下,因此针对各个版本的宿主环境做程序上的兼容也是在所难免的,以便给不同环境下的的微信用户提供可靠或者降级的服务。
[【官方文档】](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列表