# scroll-view
基礎(chǔ)庫(kù) 1.0.0 開始支持,低版本需做兼容處理。
微信 Windows 版:支持
微信 Mac 版:支持
微信 鴻蒙 OS 版:支持
相關(guān)文檔: Skyline 渲染引擎、Skyline 遷移起步
渲染框架支持情況:Skyline (使用最新 Nightly 工具調(diào)試)、WebView
# 功能描述
可滾動(dòng)視圖區(qū)域。使用豎向滾動(dòng)時(shí),需要給scroll-view一個(gè)固定高度,通過(guò) WXSS 設(shè)置 height。組件屬性的長(zhǎng)度單位默認(rèn)為px,2.4.0起支持傳入單位(rpx/px)。
- 橫向滾動(dòng)需打開 enable-flex 以兼容 WebView,如 <scroll-view scroll-x enable-flex style="flex-direction: row;"/>
- 滾動(dòng)條的長(zhǎng)度是預(yù)估的,若直接子節(jié)點(diǎn)的高度差別較大,則滾動(dòng)條長(zhǎng)度可能會(huì)不準(zhǔn)確
- 使用
worklet函數(shù)需要開啟開發(fā)者工具 "將 JS 編譯成 ES5" 或 "編譯 worklet 函數(shù)" 選項(xiàng)。
# 通用屬性
| 屬性 | 類型 | 默認(rèn)值 | 必填 | 說(shuō)明 | 最低版本 | |
|---|---|---|---|---|---|---|
| scroll-x | boolean | false | 否 | 允許橫向滾動(dòng) | 1.0.0 | |
| scroll-y | boolean | false | 否 | 允許縱向滾動(dòng) | 1.0.0 | |
| upper-threshold | number/string | 50 | 否 | 距頂部/左邊多遠(yuǎn)時(shí),觸發(fā) scrolltoupper 事件 | 1.0.0 | |
| lower-threshold | number/string | 50 | 否 | 距底部/右邊多遠(yuǎn)時(shí),觸發(fā) scrolltolower 事件 | 1.0.0 | |
| scroll-top | number/string | 否 | 設(shè)置豎向滾動(dòng)條位置 | 1.0.0 | ||
| scroll-left | number/string | 否 | 設(shè)置橫向滾動(dòng)條位置 | 1.0.0 | ||
| scroll-into-view | string | 否 | 值應(yīng)為某子元素id(id不能以數(shù)字開頭)。設(shè)置哪個(gè)方向可滾動(dòng),則在哪個(gè)方向滾動(dòng)到該元素 | 1.0.0 | ||
| scroll-into-view-offset | number | 0 | 否 | 跳轉(zhuǎn)到 scroll-into-view 目標(biāo)節(jié)點(diǎn)時(shí)的額外偏移。skyline 自 3.1.0 版本開始支持,webview 自 3.6.0 版本開始支持。 | 3.1.0 | |
| scroll-with-animation | boolean | false | 否 | 在設(shè)置滾動(dòng)條位置時(shí)使用動(dòng)畫過(guò)渡 | 1.0.0 | |
| enable-back-to-top | boolean | false | 否 | iOS點(diǎn)擊頂部狀態(tài)欄、安卓雙擊標(biāo)題欄時(shí),滾動(dòng)條返回頂部,只支持豎向。自 2.27.3 版本開始,若非顯式設(shè)置為 false,則在顯示尺寸大于屏幕 90% 時(shí)自動(dòng)開啟。鴻蒙 OS 暫不支持 | 1.0.0 | |
| enable-passive | boolean | false | 否 | 開啟 passive 特性,能優(yōu)化一定的滾動(dòng)性能 | 2.25.3 | |
| refresher-enabled | boolean | false | 否 | 開啟自定義下拉刷新 | 2.10.1 | |
| refresher-threshold | number | 45 | 否 | 設(shè)置自定義下拉刷新閾值 | 2.10.1 | |
| refresher-default-style | string | "black" | 否 | 設(shè)置自定義下拉刷新默認(rèn)樣式,支持設(shè)置 black | white | none, none 表示不使用默認(rèn)樣式 | 2.10.1 | |
| refresher-background | string | 否 | 設(shè)置自定義下拉刷新區(qū)域背景顏色,默認(rèn)為透明 | 2.10.1 | ||
| refresher-triggered | boolean | false | 否 | 設(shè)置當(dāng)前下拉刷新狀態(tài),true 表示下拉刷新已經(jīng)被觸發(fā),false 表示下拉刷新未被觸發(fā) | 2.10.1 | |
| bounces | boolean | true | 否 | iOS 下 scroll-view 邊界彈性控制 (同時(shí)開啟 enhanced 屬性后生效) | 2.12.0 | |
| show-scrollbar | boolean | true | 否 | 滾動(dòng)條顯隱控制 (同時(shí)開啟 enhanced 屬性后生效) | 2.12.0 | |
| fast-deceleration | boolean | false | 否 | 滑動(dòng)減速速率控制, 僅在 iOS 下生效 (同時(shí)開啟 enhanced 屬性后生效) | 2.12.0 | |
| binddragstart | eventhandle | 否 | 滑動(dòng)開始事件 (同時(shí)開啟 enhanced 屬性后生效) detail { scrollTop, scrollLeft } | 2.12.0 | ||
| binddragging | eventhandle | 否 | 滑動(dòng)事件 (同時(shí)開啟 enhanced 屬性后生效) detail { scrollTop, scrollLeft } | 2.12.0 | ||
| binddragend | eventhandle | 否 | 滑動(dòng)結(jié)束事件 (同時(shí)開啟 enhanced 屬性后生效) detail { scrollTop, scrollLeft, velocity } | 2.12.0 | ||
| bindscrolltoupper | eventhandle | 否 | 滾動(dòng)到頂部/左邊時(shí)觸發(fā) | 1.0.0 | ||
| bindscrolltolower | eventhandle | 否 | 滾動(dòng)到底部/右邊時(shí)觸發(fā) | 1.0.0 | ||
| bindscroll | eventhandle | 否 | 滾動(dòng)時(shí)觸發(fā),event.detail = { scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY }。skyline 從 3.6.6開始,額外具有 boundaryVelocity 字段:如果該次滾動(dòng)會(huì)觸碰到邊界,從該次滾動(dòng)觸發(fā)起到下一個(gè)滾動(dòng)事件發(fā)生或者當(dāng)次滾動(dòng)事件結(jié)束為止 boundaryVelocity 將被置為觸碰邊界時(shí)的速度,否則置為 NAN。 | 1.0.0 | ||
| bindrefresherpulling | eventhandle | 否 | 自定義下拉刷新控件被下拉 | 2.10.1 | ||
| bindrefresherrefresh | eventhandle | 否 | 自定義下拉刷新被觸發(fā) | 2.10.1 | ||
| bindrefresherrestore | eventhandle | 否 | 自定義下拉刷新被復(fù)位 | 2.10.1 | ||
| bindrefresherabort | eventhandle | 否 | 自定義下拉刷新被中止 | 2.10.1 | ||
| scroll-anchoring | boolean | false | 否 | 開啟 scroll anchoring 特性,即控制滾動(dòng)位置不隨內(nèi)容變化而抖動(dòng),可參考 CSS overflow-anchor 屬性。webview 僅在 iOS 下生效。skyline 自 3.6.2 版本開始支持,默認(rèn)為 true 。 | 2.8.2 |
# Skyline 特有屬性
| 屬性 | 類型 | 默認(rèn)值 | 必填 | 說(shuō)明 | 最低版本 | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| type | string | 否 | 渲染模式 | |||||||||||||||
| ||||||||||||||||||
| associative-container | string | 否 | 關(guān)聯(lián)的滾動(dòng)容器 | 3.2.0 | ||||||||||||||
| ||||||||||||||||||
| reverse | boolean | false | 否 | 是否反向滾動(dòng)。一般初始滾動(dòng)位置是在頂部,反向滾動(dòng)則是在底部。 | 2.27.2 | |||||||||||||
| clip | boolean | true | 否 | 是否對(duì)溢出進(jìn)行裁剪,默認(rèn)開啟 | 2.32.1 | |||||||||||||
| enable-back-to-top | boolean | false | 否 | 僅 iOS 支持,其余同 WebView 同名組件 | 2.32.1 | |||||||||||||
| cache-extent | number | 否 | 指定視口外渲染區(qū)域的距離,默認(rèn)情況下視口外節(jié)點(diǎn)不渲染。指定 cache-extent 可優(yōu)化滾動(dòng)體驗(yàn)和加載速度,但會(huì)提高內(nèi)存占用且影響首屏速度,可按需啟用。 | 2.29.0 | ||||||||||||||
| min-drag-distance | number | 18 | 否 | 指定 scroll-view 觸發(fā)滾動(dòng)的最小拖動(dòng)距離。僅在 scroll-view 和其他組件存在手勢(shì)沖突時(shí)使用,可通過(guò)調(diào)整該屬性使得滾動(dòng)更加靈敏。 | 2.33.0 | |||||||||||||
| scroll-into-view-within-extent | boolean | false | 否 | 只 scroll-into-view 到 cacheExtent 以內(nèi)的目標(biāo)節(jié)點(diǎn),性能更佳 | 2.29.0 | |||||||||||||
| scroll-into-view-alignment | string | start | 否 | 指定 scroll-into-view 目標(biāo)節(jié)點(diǎn)在視口內(nèi)的位置 | 2.29.0 | |||||||||||||
| ||||||||||||||||||
| bind:scrollstart | eventhandle | 否 | 滾動(dòng)開始事件,僅支持非 worklet 的組件方法作為回調(diào)。event.detail = { isDrag } | 2.29.0 | ||||||||||||||
| bind:scroll | eventhandle | 否 | 滾動(dòng)事件,多返回 isDrag 字段,僅支持非 worklet 的組件方法作為回調(diào)。event.detail = { isDrag } | |||||||||||||||
| bind:scrollend | eventhandle | 否 | 滾動(dòng)結(jié)束事件,僅支持非 worklet 的組件方法作為回調(diào)。event.detail = { isDrag } | 2.29.0 | ||||||||||||||
| worklet:onscrollstart | worklet | 否 | 同 bindscrollstart,但僅支持 worklet 作為回調(diào) | 2.29.2 | ||||||||||||||
| worklet:onscrollupdate | worklet | 否 | bindscroll ,但僅支持 worklet 作為回調(diào) | 2.29.2 | ||||||||||||||
| worklet:onscrollend | worklet | 否 | 同 bindscrollend,但僅支持 worklet 作為回調(diào) | 2.29.2 | ||||||||||||||
| bind:refresherwillrefresh | eventhandle | 否 | 自定義下拉刷新即將觸發(fā)刷新(拖動(dòng)超過(guò) refresher-threshold 時(shí))的事件 | 2.29.0 | ||||||||||||||
| worklet:adjust-deceleration-velocity | callback | 否 | 指定手指抬起時(shí)做慣性滾動(dòng)的初速度。(velocity: number) => number | 2.29.2 | ||||||||||||||
| padding | Array | [0, 0, 0, 0] | 否 | 長(zhǎng)度為 4 的數(shù)組,按 top、right、bottom、left 順序指定內(nèi)邊距 | 3.0.0 | |||||||||||||
| refresher-two-level-enabled | boolean | false | 否 | 開啟下拉二級(jí)能力 | 3.0.0 | |||||||||||||
| refresher-two-level-triggered | boolean | false | 否 | 設(shè)置打開/關(guān)閉二級(jí) | 3.0.0 | |||||||||||||
| refresher-two-level-threshold | number | 150 | 否 | 下拉二級(jí)閾值 | 3.0.0 | |||||||||||||
| refresher-two-level-close-threshold | number | 80 | 否 | 滑動(dòng)返回時(shí)關(guān)閉二級(jí)的閾值 | 3.0.0 | |||||||||||||
| refresher-two-level-scroll-enabled | boolean | false | 否 | 處于二級(jí)狀態(tài)時(shí)是否可滑動(dòng) | 3.0.0 | |||||||||||||
| refresher-ballistic-refresh-enabled | boolean | false | 否 | 慣性滾動(dòng)是否觸發(fā)下拉刷新 | 3.0.0 | |||||||||||||
| refresher-two-level-pinned | boolean | false | 否 | 即將打開二級(jí)時(shí)否定住 | 3.0.0 | |||||||||||||
| bind:refresherstatuschange | eventhandle | 否 | 下拉刷新狀態(tài)回調(diào) | 3.0.0 | ||||||||||||||
# WebView 特有屬性
| 屬性 | 類型 | 默認(rèn)值 | 必填 | 說(shuō)明 | 最低版本 | |
|---|---|---|---|---|---|---|
| enable-flex | boolean | false | 否 | 啟用 flexbox 布局。開啟后,當(dāng)前節(jié)點(diǎn)聲明了 display: flex 就會(huì)成為 flex container,并作用于其孩子節(jié)點(diǎn)。 | 2.7.3 | |
| enhanced | boolean | false | 否 | 啟用 scroll-view 增強(qiáng)特性,啟用后可通過(guò) ScrollViewContext 操作 scroll-view。鴻蒙 OS 暫不支持 enhanced 及其相關(guān)的屬性和方法。 | 2.12.0 | |
| paging-enabled | boolean | false | 否 | 分頁(yè)滑動(dòng)效果 (同時(shí)開啟 enhanced 屬性后生效) | 2.12.0 | |
| using-sticky | boolean | false | 否 | 使 scroll-view 下的 position sticky 特性生效,否則滾動(dòng)一屏后 sticky 元素會(huì)被隱藏 | 3.2.1 |
# Bug & Tip
tip: 基礎(chǔ)庫(kù) 2.4.0以下不支持嵌套textarea、map、canvas、video組件tip:scroll-into-view的優(yōu)先級(jí)高于scroll-toptip: 在滾動(dòng)scroll-view時(shí)會(huì)阻止頁(yè)面回彈,所以在scroll-view中滾動(dòng),是無(wú)法觸發(fā)onPullDownRefreshtip: 若要使用下拉刷新,請(qǐng)使用頁(yè)面的滾動(dòng),而不是scroll-view,這樣也能通過(guò)點(diǎn)擊頂部狀態(tài)欄回到頁(yè)面頂部tip: scroll-view 自定義下拉刷新節(jié)點(diǎn)需要聲明為 slot="refresher",可參考自定義下拉刷新示例tip: scroll-view 自定義下拉刷新可以結(jié)合 WXS 事件響應(yīng) 開發(fā)交互動(dòng)畫
# bind:refresherstatuschange
返回值 evt.detail = { status, dy },其中 status 的枚舉狀態(tài)如下
export enum RefreshStatus {
// 空閑
Idle,
// 超過(guò)下拉刷新閾值,同 bind:refresherwillRefresh 觸發(fā)時(shí)機(jī)
CanRefresh,
// 下拉刷新,同 bind:refresherrefresh 觸發(fā)時(shí)機(jī)
Refreshing,
// 下拉刷新完成,同 bind:refresherrestore 觸發(fā)時(shí)機(jī)
Completed,
// 下拉刷新失敗
Failed,
// 超過(guò)下拉二級(jí)閾值
CanTwoLevel,
// 開始打開二級(jí)
TwoLevelOpening,
// 打開二級(jí)
TwoLeveling,
// 開始關(guān)閉二級(jí)
TwoLevelClosing,
}
# 下拉二級(jí)
相關(guān)接口
- 觸發(fā)下拉刷新 ScrollViewContext.triggerRefresh
- 關(guān)閉下拉刷新 ScrollViewContext.closeRefresh
- 觸發(fā)下拉二級(jí) ScrollViewContext.triggerTwoLevel
- 關(guān)閉下拉二級(jí) ScrollViewContext.closeTwoLevel
下拉二級(jí)是下拉刷新的一部份,需同時(shí)開啟 refresher-enabled 和 refresher-two-level-enabled。
<scroll-view
type="list"
scroll-y
refresher-enabled="{{true}}"
refresher-two-level-enabled="{{true}}"
refresher-two-level-scroll-enabled="{{true}}"
>
<view slot="refresher"></view>
</scroll-view>
- 當(dāng)用戶下拉
scroll-view至refresher-threshold時(shí)松手觸發(fā)下拉刷新 - 繼續(xù)下拉至
refresher-two-level-threshold松手觸發(fā)下拉二級(jí) - 開啟
refresher-two-level-scroll-enabled后,二級(jí)頁(yè)面可以滑動(dòng)關(guān)閉,是否關(guān)閉的閾值由refresher-two-level-close-threshold指定 - 下拉刷新和下拉二級(jí)的展示區(qū)域由
slot=refresher定義,開發(fā)者可根據(jù)refresherstatuschange判定當(dāng)前階段,展示不同內(nèi)容,例如
buildText(status: RefreshStatus) {
switch (status) {
case RefreshStatus.Idle:
return '下拉刷新'
case RefreshStatus.CanRefresh:
return '松手刷新,下拉進(jìn)入二樓'
case RefreshStatus.Refreshing:
return '正在刷新'
case RefreshStatus.Completed:
return '刷新成功'
case RefreshStatus.Failed:
return '刷新失敗'
case RefreshStatus.CanTwoLevel:
return '松手進(jìn)入二樓'
default:
return ''
}
},
下拉二級(jí)示例代碼: 在開發(fā)者工具中預(yù)覽效果
# 嵌套模式
skyline 渲染模式下,當(dāng)存在兩個(gè) scroll-view 相互嵌套的場(chǎng)景時(shí),兩者的滾動(dòng)不能很絲滑的進(jìn)行銜接,故可將外層 scroll-view 改成嵌套模式,這樣可以讓兩個(gè) scroll-view 的滾動(dòng)銜接起來(lái)。
<!-- 外層 scroll-view -->
<scroll-view
type="nested"
scroll-y
refresher-enabled="{{true}}"
>
<view slot="refresher">自定義 refresher</view>
<nested-scroll-header><view>外層 scroll-vew 的節(jié)點(diǎn) 1</view></nested-scroll-header>
<nested-scroll-header><view>外層 scroll-vew 的節(jié)點(diǎn) 2</view></nested-scroll-header>
<nested-scroll-body>
<swiper>
<swiper-item>
<!-- 里層 scroll-view -->
<scroll-view type="list" associative-container="nested-scroll-view">
<view>里層 scroll-vew 的節(jié)點(diǎn) 1</view>
<view>里層 scroll-vew 的節(jié)點(diǎn) 2</view>
</scroll-view>
</swiper-item>
<swiper-item></swiper-item>
<swiper-item></swiper-item>
</swiper>
</nested-scroll-body>
</scroll-view>
- 外層
scroll-view的子節(jié)點(diǎn)只支持nested-scroll-header和nested-scroll-body和自定義 refresher - 外層
scroll-view的子節(jié)點(diǎn)中只能有一個(gè)nested-scroll-body nested-scroll-header和nested-scroll-body只能有一個(gè)子節(jié)點(diǎn)nested-scroll-header只能渲染在nested-scroll-body上面- 嵌套滾動(dòng)策略:當(dāng)向下滾動(dòng)時(shí),先滾動(dòng)外層
scroll-view再滾動(dòng)里層scroll-view;當(dāng)向上滾動(dòng)時(shí),先滾動(dòng)里層scroll-view再滾動(dòng)外層scroll-view
嵌套模式示例代碼: 在開發(fā)者工具中預(yù)覽效果
# 列表構(gòu)造器
skyline 渲染模式下,如果列表項(xiàng)特別多的場(chǎng)景可以考慮使用列表構(gòu)造器,可以實(shí)現(xiàn)可回收列表,回收的范圍取決于 cache-extent 配置。默認(rèn)情況下列表項(xiàng)進(jìn)入視口時(shí)會(huì)被創(chuàng)建,而離開視口外則會(huì)被回收,即在屏的列表項(xiàng)才會(huì)被真正創(chuàng)建出來(lái)。
<scroll-view
type="custom"
scroll-y
>
<list-builder
list="{{list}}"
child-count="{{list.length}}"
child-height="200"
bind:itembuild="onItemBuild"
bind:itemdispose="onItemDispose"
>
<view slot:item slot:index style="height: 200px;">
<view>{{index}}</view>
</view>
</list-builder>
</scroll-view>
Component({
data: {
list: [
...
]
},
methods: {
onItemBuild(evt) {
console.log('build', evt.detail.index)
},
onItemDispose(evt) {
console.log('dispose', evt.detail.index)
},
},
})
scroll-view必須設(shè)置成custom模式- 列表項(xiàng)默認(rèn)為定高模式,需要通過(guò)
child-height指定,所有列表項(xiàng)必須等高 - 不定高模式下因?yàn)闊o(wú)法知道未創(chuàng)建的列表項(xiàng)高度,會(huì)存在滾動(dòng)條跳動(dòng)問(wèn)題
- 默認(rèn)情況下不在視口中的列表項(xiàng)不會(huì)被創(chuàng)建。在滾動(dòng)過(guò)程中,會(huì)根據(jù)
child-count判斷需不需要?jiǎng)?chuàng)建/回收列表項(xiàng),如果需要?jiǎng)t會(huì)進(jìn)行列表項(xiàng)的創(chuàng)建/回收,同時(shí)觸發(fā)對(duì)應(yīng)事件 - 目前只支持縱向滾動(dòng)列表
- 不支持
scroll-into-view
列表構(gòu)造器示例代碼: 在開發(fā)者工具中預(yù)覽效果
# 網(wǎng)格構(gòu)造器
網(wǎng)格構(gòu)造器和列表構(gòu)造器的不定高模式類似,可參考列表構(gòu)造器的使用方法和注意事項(xiàng)。
<scroll-view
type="custom"
scroll-y
>
<grid-builder
list="{{list}}"
child-count="{{list.length}}"
cross-axis-count="4"
cross-axis-gap="8"
main-axis-gap="8"
>
<view slot:item slot:index style="height: 200px;">
<view>{{index}}</view>
</view>
</grid-builder>
</scroll-view>
Component({
data: {
list: [
...
]
},
})
網(wǎng)格構(gòu)造器示例代碼: 在開發(fā)者工具中預(yù)覽效果
# 示例代碼
自定義下拉刷新示例代碼: 在開發(fā)者工具中預(yù)覽效果