tencent cloud

腾讯云超级应用服务

动态与公告
【2025年1月2日】关于腾讯云小程序平台更名为腾讯云超级应用服务的公告
控制台更新动态
Android SDK 更新动态
iOS SDK 更新动态
Flutter 更新动态
IDE 更新动态
基础库更新动态
产品简介
产品概述
产品优势
应用场景
购买指南
计费概述
按量计费(后付费)
续费指引
停服说明
快速入门
套餐管理
概述
控制台账号管理
存储配置
加速配置
品牌化配置
平台功能
控制台登录
用户和权限体系
小程序管理
小游戏管理
应用管理
商业化
平台管理
用户管理
团队管理
运营管理
安全中心
代码接入指引
Demo 及 SDK 获取
Android
iOS
Flutter
App 服务端接入指南
GUID 生成规则
小程序开发指南
小程序介绍与开发环境
小程序代码组成
指南
框架
组件
API
服务端
JS SDK
基础库
IDE 使用指南
小游戏开发指南
指南
API
服务端
实践教程
小程序登录实践教程
小程序订阅消息实践教程
支付相关实践教程
广告接入实践教程
小游戏订阅消息实践教程
相关协议
数据处理和安全协议

渲染层

PDF
聚焦模式
字号
最后更新时间: 2025-12-08 15:20:57
框架的渲染层由 WXML 与 WXSS 编写,由组件来进行展示。将逻辑层的数据反映成视图,同时将渲染层的事件发送给逻辑层。
WXML(WX Markup language) 用于描述页面的结构。
WXS(WX Script) 是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
WXSS(WX Style Sheet) 用于描述页面的样式。
组件(Component)是视图的基本组成单元。

1. WXML

WXML(WX Markup Language)是框架设计的一套标签语言,结合基础组件事件系统可以构建出页面的结构。
要完整了解 WXML 语法,请参考 WXML 语法参考
用以下一些简单的例子来看看 WXML 具有什么能力:

1.1 数据绑定

<!-- wxml -->
<view> {{message}} </view>
// page.js
Page({
data: {
message: 'Hello MINA!'
}
})

1.2 列表渲染

<!--wxml-->
<view wx:for="{{array}}"> {{item}} </view>

1.3 条件渲染

<!--wxml-->
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
// page.js
Page({
data: {
view: 'MINA'
}
})

1.4 模板

<!--wxml-->
<template name="staffName">
<view>
FirstName: {{firstName}}, LastName: {{lastName}}
</view>
</template>

<template is="staffName" data="{{...staffA}}"></template>
<template is="staffName" data="{{...staffB}}"></template>
<template is="staffName" data="{{...staffC}}"></template>
// page.js
Page({
data: {
staffA: {firstName: 'Hulk', lastName: 'Hu'},
staffB: {firstName: 'Shang', lastName: 'You'},
staffC: {firstName: 'Gideon', lastName: 'Lin'}
}
})

2. WXSS

WXSS (WX Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。
WXSS 用来决定 WXML 的组件应该怎么显示。
为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发小程序,WXSS 对 CSS 进行了扩充以及修改。
与 CSS 相比,WXSS 扩展的特性有:
尺寸单位
样式导入
注意:
iOS 8 及以下的 iOS 版本,如使用 flexbox 布局,需添加display: -webkit-flex属性。

2.1 尺寸单位

rpx(responsive pixel):可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
根据不同的设备屏幕宽度,rpx 和 px 的换算关系也会有所不同。例如:
设备
屏幕宽度
rpx 换算 px(屏幕宽度/750)
px 换算 rpx (750/屏幕宽度)
iPhone5
320px
1rpx = 0.42px
1px = 2.34rpx
iPhone6
375px
1rpx = 0.5px
1px = 2rpx
iPhone6 Plus
414px
1rpx = 0.552px
1px = 1.81rpx
说明:
建议: 开发小程序时设计师可以用 iPhone6 作为视觉稿的标准。
注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。

2.2 样式导入

使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。
示例代码:
/** common.wxss **/
.small-p {
padding:5px;
}
/** app.wxss **/
@import "common.wxss";
.middle-p {
padding:15px;
}

2.3 内联样式

框架组件上支持使用 style、class 属性来控制组件的样式。
style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。
/** common.wxss **/
.small-p {
padding:5px;
}
class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上,样式类名之间用空格分隔。
<view class="normal_view" />

2.4 选择器

目前支持的选择器有:
选择器
样例
样例描述
.class
.intro
选择所有拥有 class="intro" 的组件
#id
#firstname
选择拥有 id="firstname" 的组件
element
view
选择所有 view 组件
element,element
view, checkbox
选择所有文档的 view 组件和所有的 checkbox 组件
::after
view::after
在 view 组件后边插入内容
::before
view::before
在 view 组件前边插入内容

2.5 全局样式与局部样式

定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。

3. WXS

WXS(WX Script)是内联在 WXML 中的脚本段。通过 WXS 可以在模板中内联少量处理脚本,丰富模板的数据预处理能力。另外,WXS 还可以用来编写简单的 WXS 事件响应函数
从语法上看,WXS 类似于有少量限制的 JavaScript 。要完整了解 WXS 语法,请参考WXS - 介绍
以下是一些使用 WXS 的简单示例。 页面渲染:
<!--wxml-->
<wxs module="m1">
var msg = "hello world";

module.exports.message = msg;
</wxs>

<view> {{m1.message}} </view>
页面输出:
hello world
数据处理:
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5, 1, 2, 3, 4]
}
})
<!--wxml-->
<!-- 下面的 getMax 函数,接受一个数组,且返回数组中最大的元素的值 -->
<wxs module="m1">
var getMax = function(array) {
var max = undefined;
for (var i = 0; i < array.length; ++i) {
max = max === undefined ?
array[i] :
(max >= array[i] ? max : array[i]);
}
return max;
}

module.exports.getMax = getMax;
</wxs>

<!-- 调用 wxs 里面的 getMax 函数,参数为 page.js 里面的 array -->
<view> {{m1.getMax(array)}} </view>
页面输出:
5

4. 事件系统

4.1 什么是事件

事件是渲染层到逻辑层的通讯方式。
事件可以将用户的行为反馈到逻辑层进行处理。
事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
事件对象可以携带额外信息,如 id, dataset, touches。

4.2 事件的使用方式

在组件中绑定一个事件处理函数。
bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。
<view id="tapTest" data-hi="Weixin" bindtap="tapName"> Click me! </view>
在相应的Page定义中写上相应的事件处理函数,参数是event
Page({
tapName: function(event) {
console.log(event)
}
})
可以看到log出来的信息大致如下:
{
"type":"tap",
"timeStamp":895,
"target": {
"id": "tapTest",
"dataset": {
"hi":"Weixin"
}
},
"currentTarget": {
"id": "tapTest",
"dataset": {
"hi":"Weixin"
}
},
"detail": {
"x":53,
"y":14
},
"touches":[{
"identifier":0,
"pageX":53,
"pageY":14,
"clientX":53,
"clientY":14
}],
"changedTouches":[{
"identifier":0,
"pageX":53,
"pageY":14,
"clientX":53,
"clientY":14
}]
}

4.3 使用WXS函数响应事件

4.3.1 背景

有频繁用户交互的效果在小程序上表现是比较卡顿的,例如页面有2个元素 A 和 B,用户在 A 上做 touchmove 手势,要求 B 也跟随移动,movable-view 就是一个典型的例子。一次 touchmove 事件的响应过程为:
touchmove 事件从渲染层(Webview)抛到逻辑层(App Service);
逻辑层(App Service)处理 touchmove 事件,再通过 setData 来改变 B 的位置。
一次 touchmove 的响应需要经过 2 次的逻辑层和渲染层的通信以及一次渲染,通信的耗时比较大。此外 setData 渲染也会阻塞其它脚本执行,导致了整个用户交互的动画过程会有延迟。

4.3.2 解决方案

本方案基本的思路是减少通信的次数,让事件在渲染层(Webview)响应。小程序的框架分为渲染层(Webview)和逻辑层(App Service),这样分层的目的是管控,开发者的代码只能运行在逻辑层(App Service),而这个思路就必须要让开发者的代码运行在渲染层(Webview)。
使用 WXS 函数用来响应小程序事件,目前只能响应内置组件的事件,不支持自定义组件事件。
WXS 函数的除了纯逻辑的运算,还可以通过封装好的 ComponentDescriptor 实例来访问以及设置组件的 class 和样式,对于交互动画,设置 style 和 class 足够了。
WXS 函数接受2个参数,第一个是 event,在原有的 event 的基础上加了event.instance对象,第二个参数是ownerInstanceevent.instance一样是一个ComponentDescriptor对象。具体使用如下:
在组件中绑定和注册事件处理的 WXS 函数:
<wxs module="wxs" src="./test.wxs"></wxs>
<view id="tapTest" data-hi="Weixin" bindtap="{{wxs.tapName}}"> Click me! </view>
**注:绑定的WXS函数必须用{{}}括起来**
test.wxs 文件实现 tapName 函数:
function tapName(event, ownerInstance) {
console.log('tap Weixin', JSON.stringify(event))
}
module.exports = {
tapName: tapName
}
ownerInstance 包含了一些方法,可以设置组件的样式和 class。
WXS 函数的例子如下:
var wxsFunction = function(event, ownerInstance) {
var instance = ownerInstance.selectComponent('.classSelector') // 返回组件的实例
instance.setStyle({
"font-size": "14px" // 支持rpx
})
instance.getDataset()
instance.setClass(className)
// ...
return false // 不往上冒泡,相当于调用了同时调用了stopPropagation和preventDefault
}
其中入参 event 是小程序事件对象基础上多了 event.instance 来表示触发事件的组件的 ComponentDescriptor 实例。
ownerInstance 表示的是触发事件的组件所在的组件的 ComponentDescriptor 实例,如果触发事件的组件是在页面内的,则 ownerInstance 表示的是页面实例。
ComponentDescriptor 目前支持的 API 如下:
方法
参数
描述
selectComponent
selector 对象
返回组件的 ComponentDescriptor 实例。
selectAllComponents
selector对象数组
返回组件的 ComponentDescriptor 实例数组。
setStyle
Object/string
设置组件样式,支持rpx。设置的样式优先级比组件 wxml 里面定义的样式高。不能设置最顶层页面的样式。
addClass/removeClass/hasClass
string
设置组件的 class。设置的 class 优先级比组件 wxml 里面定义的 class 高。不能设置最顶层页面的 class。
getDataset
返回当前组件/页面的 dataset 对象。
callMethod
(funcName:string, args:object)
调用当前组件/页面在逻辑层(App Service)定义的函数。funcName 表示函数名称,args 表示函数的参数。
getState
返回一个 object 对象,当有局部变量需要存储起来后续使用的时候用这个方法。
triggerEvent
(eventName, detail)
和组件的triggerEvent一致。

4.3.3 使用方法

WXML 定义事件:
<wxs module="test" src="./test.wxs"></wxs>
<view
change:prop="{{test.propObserver}}"
prop="{{propValue}}"
bindtouchmove="{{test.touchmove}}"
class="movable">
</view>
上面的 change:prop(属性前面带 change: 前缀)是在 prop 属性被设置的时候触发 WXS 函数,值必须用{{}} 括起来。类似 Component 定义的 properties 里面的 observer 属性,在 setData({propValue: newValue}) 调用之后会触发。
注意:
WXS 函数必须用 {{}} 括起来。当 prop 的值被设置 WXS 函数就会触发,而不只是值发生改变,所以在页面初始化的时候会调用一次 WxsPropObserver 的函数。
WXS 文件 test.wxs 里面定义并导出事件处理函数和属性改变触发的函数:
module.exports = {
touchmove: function(event, instance) {
console.log('log event', JSON.stringify(event))
},
propObserver: function(newValue, oldValue, ownerInstance, instance) {
console.log('prop observer', newValue, oldValue)
}
}

4.4 事件详解

4.4.1 事件分类

事件分为冒泡事件和非冒泡事件:
冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递;
非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
WXML的冒泡事件列表:
类型
触发条件
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 动画完成时触发
touchforcechange
在支持 3D Touch 的 iPhone 设备,重按时会触发
说明:
除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 form 的submit事件,input 的input事件,scroll-view 的scroll事件,(详见 组件概览)

4.4.2 普通事件绑定

事件绑定的写法类似于组件的属性,如:
<view bindtap="handleTap">
Click here!
</view>
如果用户点击这个 view ,则页面的 handleTap 会被调用。
事件绑定函数可以是一个数据绑定,如:
<view bindtap="{{ handlerName }}">
Click here!
</view>
此时,页面的 this.data.handlerName 必须是一个字符串,指定事件处理函数名;如果它是个空字符串,则这个绑定会失效(可以利用这个特性来暂时禁用一些事件)。
在大多数组件和自定义组件中, bind 后可以紧跟一个冒号,其含义不变,如 bind:tap

4.4.3 绑定并阻止事件冒泡

bind外,也可以用catch来绑定事件。与bind不同,catch会阻止事件向上冒泡。
例如在下边这个例子中,单击 inner view 会先后调用handleTap3handleTap2(因为 tap 事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递),单击 middle view 会触发handleTap2,单击 outer view 会触发handleTap1
<view id="outer" bindtap="handleTap1">
outer view
<view id="middle" catchtap="handleTap2">
middle view
<view id="inner" bindtap="handleTap3">
inner view
</view>
</view>
</view>

4.4.4 互斥事件绑定

自基础库版本 1.5.44 起,除 bindcatch 外,还可以使用 mut-bind 来绑定事件。一个 mut-bind 触发后,如果事件冒泡到其他节点上,其他节点上的 mut-bind绑定函数不会被触发,但 bind 绑定函数和 catch 绑定函数依旧会被触发。
换而言之,所有 mut-bind 是“互斥”的,只会有其中一个绑定函数被触发。同时,它完全不影响 bindcatch 的绑定效果。
例如在下边这个例子中,单击 inner view 会先后调用 handleTap3handleTap2 ,单击 middle view 会调用 handleTap2handleTap1
<view id="outer" mut-bind:tap="handleTap1">
outer view
<view id="middle" bindtap="handleTap2">
middle view
<view id="inner" mut-bind:tap="handleTap3">
inner view
</view>
</view>
</view>

4.4.5 事件的捕获阶段

触摸类事件支持捕获阶段。捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。需要在捕获阶段监听事件时,可以采用capture-bindcapture-catch关键字,后者将中断捕获阶段和取消冒泡阶段。
在下面的代码中,单击 inner view 会先后调用handleTap2handleTap4handleTap3handleTap1
<view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2">
outer view
<view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
inner view
</view>
</view>
如果将上面代码中的第一个 capture-bind 改为 capture-catch,将只触发 handleTap2。
<view id="outer" bind:touchstart="handleTap1" capture-catch:touchstart="handleTap2">
outer view
<view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
inner view
</view>
</view>

4.4.6 事件对象

如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。
BaseEvent 基础事件对象属性列表:
属性
类型
说明
type
String
事件类型
timeStamp
Integer
事件生成时的时间戳
target
Object
触发事件的组件的一些属性值集合
currentTarget
Object
当前组件的一些属性值集合
CustomEvent 自定义事件对象属性列表(继承 BaseEvent):
属性
类型
说明
detail
Object
额外的信息
TouchEvent 触摸事件对象属性列表(继承 BaseEvent):
属性
类型
说明
touches
Array
触摸事件,当前停留在屏幕中的触摸点信息的数组
changedTouches
Array
触摸事件,当前变化的触摸点信息的数组
特殊事件:canvas 中的触摸事件不可冒泡,所以没有 currentTarget。

4.4.7 type

代表事件的类型。

4.4.8 timeStamp

页面打开到触发事件所经过的毫秒数。

4.4.9 target

触发事件的源组件。
属性
类型
说明
id
String
事件源组件的 id
dataset
Object
事件源组件上由 data - 开头的自定义属性组成的集合

4.4.10 currentTarget

事件绑定的当前组件。
属性
类型
说明
id
String
当前组件的 id
dataset
Object
当前组件上由 data - 开头的自定义属性组成的集合
说明:
target 和 currentTarget 可以参考上例中,单击 inner view 时,handleTap3 收到的事件对象 target 和 currentTarget 都是 inner,而 handleTap2 收到的事件对象 target 就是 inner,currentTarget 就是 middle。

4.4.11 dataset

在组件节点中可以附加一些自定义数据。这样,在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理。
在 WXML 中,这些自定义数据以 data- 开头,多个单词由连字符 - 连接。这种写法中,连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符。如:
data-element-type ,最终会呈现为 event.currentTarget.dataset.elementType ;
data-elementType ,最终会呈现为 event.currentTarget.dataset.elementtype 。
代码示例:
<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view>

Page({
bindViewTap:function(event){
event.currentTarget.dataset.alphaBeta === 1 // - 会转为驼峰写法
event.currentTarget.dataset.alphabeta === 2 // 大写会转为小写
}
})

4.4.12 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轴

4.4.13 changedTouches

changedTouches 数据格式同 touches。 表示有变化的触摸点,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel)。

4.4.14 detail

自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见 组件概览 定义中各个事件的定义。
单击事件的detail 带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离。

5. 基础组件

框架为开发者提供了一系列基础组件,开发者可以通过组合这些基础组件进行快速开发。详细介绍请参考 组件概览
什么是组件:
组件是视图层的基本组成单元。
一个组件通常包括开始标签结束标签属性用来修饰这个组件,内容在两个标签之内。
<tagname property="value">
Content goes here ...
</tagname>
注意:
所有组件与属性都是小写,以连字符-连接。
属性类型:
类型
描述
注解
Boolean
布尔值
组件写上该属性,不管是什么值都被当作 true;只有组件上没有该属性时,属性值才为false。 如果属性值为变量,变量的值会被转换为 Boolean 类型。
Number
数字
1, 2.5
String
字符串
"string"
Array
数组
[ 1, "string" ]
Object
对象
{ key: value }
EventHandler
事件处理函数名
"handlerName" 是 Page 中定义的事件处理函数名
Any
任意属性
-
公共属性
所有组件都有以下属性:
属性名
类型
描述
注解
id
String
组件的唯一标示
保持整个页面唯一
class
String
组件的样式类
在对应的 WXSS 中定义的样式类
style
String
组件的内联样式
可以动态设置的内联样式
hidden
Boolean
组件是否显示
所有组件默认显示
data-*
Any
自定义属性
组件上触发的事件时,会发送给事件处理函数
bind* / catch*
EventHandler
组件的事件
详见事件
特殊属性
几乎所有组件都有各自定义的属性,可以对该组件的功能或样式进行修饰,请参考各个 组件概览 的定义。

6. 获取界面上的节点信息

6.1 WXML节点信息

节点信息查询 API 可以用于获取节点属性、样式、在界面上的位置等信息。
最常见的用法是使用这个接口来查询某个节点的当前位置,以及界面的滚动位置。
示例代码:
const query = wx.createSelectorQuery()
query.select('#the-id').boundingClientRect(function(res){
res.top // #the-id 节点的上边界坐标(相对于显示区域)
})
query.selectViewport().scrollOffset(function(res){
res.scrollTop // 显示区域的竖直滚动位置
})
query.exec()
上述示例中, #the-id 是一个节点选择器,与 CSS 的选择器相近但略有区别,请参见 SelectorQuery.select 的相关说明。
在自定义组件或包含自定义组件的页面中,推荐使用 this.createSelectorQuery 来代替 wx.createSelectorQuery,这样可以确保在正确的范围内选择节点。

6.2 WXML节点布局相交状态

节点布局相交状态 API 可用于监听两个或多个组件节点在布局位置上的相交状态。这一组 API 常常可以用于推断某些节点是否可以被用户看见、有多大比例可以被用户看见。
这一组 API 涉及的主要概念如下。
参照节点:监听的参照节点,取它的布局区域作为参照区域。如果有多个参照节点,则会取它们布局区域的 交集 作为参照区域。页面显示区域也可作为参照区域之一;
目标节点:监听的目标,默认只能是一个节点(使用 selectAll 选项时,可以同时监听多个节点);
相交区域:目标节点的布局区域与参照区域的相交区域;
相交比例:相交区域占参照区域的比例;
阈值:相交比例如果达到阈值,则会触发监听器的回调函数。阈值可以有多个;
以下示例代码可以在目标节点(用选择器 .target-class指定)每次进入或离开页面显示区域时,触发回调函数。
示例代码:
Page({
onLoad: function(){
wx.createIntersectionObserver().relativeToViewport().observe('.target-class', (res) => {
res.id // 目标节点 id
res.dataset // 目标节点 dataset
res.intersectionRatio // 相交区域占目标节点的布局区域的比例
res.intersectionRect // 相交区域
res.intersectionRect.left // 相交区域的左边界坐标
res.intersectionRect.top // 相交区域的上边界坐标
res.intersectionRect.width // 相交区域的宽度
res.intersectionRect.height // 相交区域的高度
})
}
})
以下示例代码可以在目标节点(用选择器 .target-class 指定)与参照节点(用选择器 .relative-class 指定)在页面显示区域内相交或相离,且相交或相离程度达到目标节点布局区域的20%和50%时,触发回调函数。
示例代码:
Page({
onLoad: function(){
wx.createIntersectionObserver(this, {
thresholds: [0.2, 0.5]
}).relativeTo('.relative-class').relativeToViewport().observe('.target-class', (res) => {
res.intersectionRatio // 相交区域占目标节点的布局区域的比例
res.intersectionRect // 相交区域
res.intersectionRect.left // 相交区域的左边界坐标
res.intersectionRect.top // 相交区域的上边界坐标
res.intersectionRect.width // 相交区域的宽度
res.intersectionRect.height // 相交区域的高度
})
}
})
注意:
与页面显示区域的相交区域并不准确代表用户可见的区域,因为参与计算的区域是“布局区域”,布局区域可能会在绘制时被其他节点裁剪隐藏(如遇祖先节点中 overflow 样式为 hidden 的节点)或遮盖(如遇 fixed 定位的节点)。
在自定义组件或包含自定义组件的页面中,推荐使用 this.createIntersectionObserver 来代替 wx.createIntersectionObserver ,这样可以确保在正确的范围内选择节点。

7. 响应显示区域变化

7.1 显示区域尺寸

显示区域指小程序界面中可以自由布局展示的区域。在默认情况下,小程序显示区域的尺寸自页面初始化起就不会发生变化。但以下三种方式都可以改变这一默认行为。
在手机上启用屏幕旋转支持
小程序在手机上支持屏幕旋转。使小程序中的页面支持屏幕旋转的方法是:在 app.jsonwindow 段中设置 "pageOrientation": "auto" ,或在页面 json 文件中配置 "pageOrientation": "auto"
以下是在单个页面 json 文件中启用屏幕旋转的示例。
代码示例:
{
"pageOrientation": "auto"
}
如果页面添加了上述声明,则在屏幕旋转时,这个页面将随之旋转,显示区域尺寸也会随着屏幕旋转而变化。pageOrientation 还可以被设置为 landscape ,表示固定为横屏显示。
在iPad上启用屏幕旋转支持
在 iPad 上运行的小程序可以支持屏幕旋转。使小程序支持 iPad 屏幕旋转的方法是:在 app.json 中添加 "resizable": true 。
代码示例:
{
"resizable": true
}
如果小程序添加了上述声明,则在屏幕旋转时,小程序将随之旋转,显示区域尺寸也会随着屏幕旋转而变化。
注意:
在 iPad 上不能单独配置某个页面是否支持屏幕旋转。

7.2 Media Query

有时,对于不同尺寸的显示区域,页面的布局会有所差异。此时可以使用 media query 来解决大多数问题。
代码示例:
.my-class {
width: 40px;
}

@media (min-width: 480px) {
/* 仅在 480px 或更宽的屏幕上生效的样式规则 */
.my-class {
width: 200px;
}
}

7.3 屏幕旋转事件

有时,仅仅使用 media query 无法控制一些精细的布局变化。此时可以使用 js 作为辅助。
在 js 中读取页面的显示区域尺寸,可以使用 selectorQuery.selectViewport
页面尺寸发生改变的事件,可以使用页面的 onResize 来监听。对于自定义组件,可以使用 resize 生命周期来监听。回调函数中将返回显示区域的尺寸信息。
代码示例:
Page({
onResize(res) {
res.size.windowWidth // 新的显示区域宽度
res.size.windowHeight // 新的显示区域高度
}
})
Component({
pageLifetimes: {
resize(res) {
res.size.windowWidth // 新的显示区域宽度
res.size.windowHeight // 新的显示区域高度
}
}
})
此外,还可以使用 wx.onWindowResize 来监听(但这不是推荐的方式)。

8. 页面动画

8.1 界面动画的常见方式

在小程序中,通常可以使用 CSS 渐变 和 CSS 动画 来创建简易的界面动画。
动画过程中,可以使用 bindtransitionend bindanimationstart bindanimationiteration bindanimationend 来监听动画事件。
事件名
含义
transitionend
CSS 渐变结束或 wx.createAnimation 结束一个阶段
animationstart
CSS 动画开始
animationiteration
CSS 动画结束一个阶段
animationend
CSS 动画结束
说明:
这几个事件都不是冒泡事件,需要绑定在真正发生了动画的节点上才会生效。
同时,还可以使用 wx.createAnimation 接口来动态创建简易的动画效果(新版小程序基础库中推荐使用下述的关键帧动画接口代替)。

8.2 高级的动画方式

在一些复杂场景下,上述的动画方法可能并不适用。
WXS 响应事件 的方式可以通过使用 WXS 来响应事件的方法来动态调整节点的 style 属性。通过不断改变 style 属性的值可以做到动画效果。同时,这种方式也可以根据用户的触摸事件来动态地生成动画。
连续使用 setData 来改变界面的方法也可以达到动画的效果。这样可以任意地改变界面,但通常会产生较大的延迟或卡顿,甚至导致小程序僵死。此时可以通过将页面的 setData 改为 自定义组件 中的 setData 来提升性能。


帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈