可滚动视图区域,相当于web中设置了overflow属性的div元素。
起始版本: 1.0.0
约束与限制:
使用竖向滚动时,需要通过CSS设置height,给scroll-view一个固定高度。组件属性的长度单位默认为px。
属性:
| 名称 | 类型 | 默认值 | 必填 | 描述 |
|---|---|---|---|---|
| enhanced | boolean | false | 否 | 是否启用scroll-view增强特性,启用后可通过ScrollViewContext操作scroll-view。 起始版本: 1.0.23 |
| scroll-x | boolean | false | 否 | 允许横向滚动。 |
| scroll-y | boolean | false | 否 | 允许纵向滚动。 |
| upper-threshold | number|string | 50 | 否 | 距顶部/左边多远时,触发scrolltoupper事件。 |
| lower-threshold | number|string | 50 | 否 | 距底部/右边多远时,触发scrolltolower事件。 |
| scroll-top | number|string | 0 | 否 | 设置竖向滚动条位置。 |
| scroll-left | number|string | 0 | 否 | 设置横向滚动条位置。 |
| scroll-into-view | string | - | 否 | 值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素。 |
| scroll-into-view-offset | number | 0 | 否 | 跳转到scroll-into-view目标节点时的额外偏移。 起始版本: 2.0.1 |
| scroll-with-animation | boolean | false | 否 | 在设置滚动条位置时使用动画过渡。 |
| show-scrollbar | boolean | true | 否 | 2.0.1版本之前,滚动条显隐控制(没有其它额外限制)。 2.0.1版本之后,滚动条显隐控制(同时开启enhanced属性后生效)。 |
| refresher-enabled | boolean | false | 否 | 开启自定义下拉刷新。 |
| refresher-threshold | number | 45 | 否 | 设置自定义下拉刷新阈值。 |
| refresher-default-style | string | "black" | 否 | 设置自定义下拉刷新默认样式,支持设置black | white | none,none表示不使用默认样式。 |
| refresher-background | string | transparent | 否 | 设置自定义下拉刷新区域背景颜色,默认为透明。 |
| refresher-triggered | boolean | false | 否 | 设置当前下拉刷新状态,true表示下拉刷新已经被触发,false表示下拉刷新未被触发。 |
| bounces | boolean | true | 否 | 边界弹性控制(同时开启enhanced属性后生效)。 起始版本: 2.0.1 |
| fast-deceleration | boolean | false | 否 | 滑动减速速率控制(同时开启enhanced属性后生效)。 起始版本: 2.0.1 |
| scroll-anchoring | boolean | false | 否 | 开启scroll anchoring特性,即控制滚动位置不随内容变化而抖动。 起始版本: 2.0.1 |
| enable-flex | boolean | false | 否 | 启用flexbox布局。开启后,当前节点声明了display: flex就会成为flex container,并作用于其孩子节点。 起始版本: 2.0.1 |
| paging-enabled | boolean | false | 否 | 开启分页滚动(同时开启enhanced属性后生效)。 起始版本: 2.0.1 |
| using-sticky | boolean | false | 否 | 使scroll-view下的position: sticky特性生效。 起始版本: 2.0.1 |
refresher-default-style设置为none时,在<scroll-view>下声明slot="refresher"的节点,可实现下拉刷新自定义内容,具体参考下面的下拉刷新自定义内容示例。
起始版本: 1.0.23
事件:
| 名称 | 参数 | 描述 |
|---|---|---|
| bindscrolltoupper | eventhandle | 滚动到顶部/左边时触发。 |
| bindscrolltolower | eventhandle | 滚动到底部/右边时触发。 |
| bindscroll | eventhandle | 滚动时触发。 |
| binddragstart | eventhandle | 滑动开始事件(同时开启enhanced属性后生效)。 起始版本: 2.0.1 |
| binddragging | eventhandle | 滑动事件(同时开启enhanced属性后生效)。 起始版本: 2.0.1 |
| binddragend | eventhandle | 滑动结束事件(同时开启enhanced属性后生效)。 起始版本: 2.0.1 |
| bindrefresherpulling | eventhandle | 自定义下拉刷新控件被下拉。 |
| bindrefresherrefresh | eventhandle | 自定义下拉刷新被触发。 |
| bindrefresherrestore | eventhandle | 自定义下拉刷新被复位。 |
| bindrefresherabort | eventhandle | 自定义下拉刷新被中止。 |
示例:
hxml文件:
<scroll-view
scroll-y="{{scrollY}}"
style="height: 50px"
upper-threshold="50"
lower-threshold="30px"
bindscrolltoupper="scrollToUpperEvent"
bindscrolltolower="scrollToLowerEvent"
bindscroll="scrollEvent"
bindrefresherpulling="refresherPullingEvent"
bindrefresherrefresh="refresherRefreshEvent"
bindrefresherrestore="refresherRestoreEvent"
bindrefresherabort="refresherAbortEvent">
<view id="demo1" class="scroll-view-item demo-text-1">1</view>
<view id="demo2" class="scroll-view-item demo-text-2">2</view>
<view id="demo3" class="scroll-view-item demo-text-3">3</view>
</scroll-view>
<view>自定义下拉刷新事件</view>
<scroll-view
class="page-section page-section-gap"
scroll-y="{{scrollY}}"
refresher-enabled="{{true}}"
style="height: 500px"
upper-threshold="50"
lower-threshold="30px"
bindscrolltoupper="scrollToUpperEvent"
bindscrolltolower="scrollToLowerEvent"
bindscroll="scrollEvent"
bindrefresherpulling="refresherPullingEvent"
bindrefresherrefresh="refresherRefreshEvent"
bindrefresherrestore="refresherRestoreEvent"
bindrefresherabort="refresherAbortEvent">
<view id="demo1" class="scroll-view-item demo-text-1">3</view>
<view id="demo2" class="scroll-view-item demo-text-2">4</view>
<view id="demo3" class="scroll-view-item demo-text-3">5</view>
</scroll-view> js文件:
Page({
data: {
scrollY: true,
height: 50
},
scrollToUpperEvent(event) {
// event.detail内容举例为:{"direction":""}
console.info('scroll-view组件滚动到顶部/左边时触发,携带值为:', event.detail);
},
scrollToLowerEvent(event) {
// event.detail内容举例为:{"direction":""}
console.info('scroll-view组件滚动到底部/右边时触发,携带值为:', event.detail);
},
scrollEvent(event) {
// event.detail内容举例为:{"scrollTop":0,"scrollLeft":0,"scrollWidth":0,"scrollHeight":0,"deltaY":0,"deltaX":0}
console.info('scroll-view组件滚动时触发,携带值为:', event.detail);
},
refresherPullingEvent(event) {
// event.detail内容举例为:{"dy":0}
console.info('scroll-view组件自定义下拉刷新控件被下拉触发,携带值为:', event.detail);
},
refresherRefreshEvent(event) {
// event.detail内容举例为:{"dy":0}
console.info('scroll-view组件自定义下拉刷新被触发,携带值为:', event.detail);
},
refresherRestoreEvent(event) {
// event.detail内容举例为:{"dy":0}
console.info('scroll-view组件自定义下拉刷新被复位触发,携带值为:', event.detail);
},
refresherAbortEvent(event) {
// event.detail内容举例为:{"dy":0}
console.info('scroll-view组件自定义下拉刷新被中止触发,携带值为:', event.detail);
}
}); hxml文件:
<view>
<scroll-view
style="width: 100%; height: 100vh"
scroll-y="{{scrollY}}"
refresher-enabled="{{refresherEnabled}}"
refresher-threshold="{{refresherThreshold}}"
refresher-default-style="{{refresherDefaultStyle}}"
refresher-triggered="{{refresherTriggered}}"
bindrefresherrefresh="refresherRefreshEvent">
<view slot="refresher" class="custom-refresher">
<view class="refresher-text">
<text>下拉刷新中...</text>
</view>
</view>
<view>
<view class="scroll-view-item">列表内容1</view>
<view class="scroll-view-item">列表内容2</view>
<view class="scroll-view-item">列表内容3</view>
</view>
</scroll-view>
</view> js文件:
Page({
data: {
scrollY: true,
refresherEnabled: true,
refresherThreshold: 45,
refresherDefaultStyle: 'none',
refresherTriggered: false
},
timeoutId: null,
refresherRefreshEvent() {
this.setData({
refresherTriggered: true
});
if (this.timeoutId) {
clearTimeout(this.timeoutId);
}
// 模拟内容刷新
this.timeoutId = setTimeout(() => {
this.setData({
refresherTriggered: false
});
this.timeoutId = null;
}, 2000);
}
}); css文件:
.custom-refresher {
width: 100%;
height: 45px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.refresher-text {
font-size: 28rpx;
color: white;
font-weight: 500;
}
.scroll-view-item {
padding: 50rpx;
} hxml文件:
<view>
<scroll-view
style="width: 100%; height: 200px"
scroll-y="{{scrollY}}"
bounces="{{bounces}}"
enhanced="{{enhanced}}">
<view>
<view class="scroll-view-item">列表内容1</view>
<view class="scroll-view-item">列表内容2</view>
<view class="scroll-view-item">列表内容3</view>
</view>
</scroll-view>
</view> js文件:
Page({
data: {
scrollY: true,
bounces: true,
enhanced: true
}
}); css文件:
.scroll-view-item {
height: 100px;
background-color: aliceblue;
} hxml文件:
<view>
<scroll-view
style="width: 100%; height: 200px"
scroll-y="{{scrollY}}"
enhanced="{{enhanced}}"
binddragstart="onDragStart"
binddragging="onDragging"
binddragend="onDragEnd">
<view>
<view class="scroll-view-item">列表内容1</view>
<view class="scroll-view-item">列表内容2</view>
<view class="scroll-view-item">列表内容3</view>
</view>
</scroll-view>
</view> js文件:
Page({
data: {
scrollY: true,
enhanced: true
},
onDragStart(event) {
// event.detail内容举例为:{"scrollTop":"","scrollLeft":""}
console.info('scroll-view组件开始滑动时触发,携带值为:', event.detail);
},
onDragging(event) {
// event.detail内容举例为:{"scrollTop":"","scrollLeft":""}
console.info('scroll-view组件滑动中触发,携带值为:', event.detail);
},
onDragEnd(event) {
// event.detail内容举例为:{"scrollTop":"","scrollLeft":"","velocity":{"x":"","y":""}}
console.info('scroll-view组件滑动结束时触发,携带值为:', event.detail);
}
}); css文件:
.scroll-view-item {
height: 100px;
background-color: aliceblue;
} hxml文件:
<view>
<scroll-view
style="width: 100%; height: 200px"
scroll-y="{{scrollY}}"
fast-deceleration="{{fastDeceleration}}"
enhanced="{{enhanced}}">
<view>
<view class="scroll-view-item">列表内容1</view>
<view class="scroll-view-item">列表内容2</view>
<view class="scroll-view-item">列表内容3</view>
<view class="scroll-view-item">列表内容4</view>
<view class="scroll-view-item">列表内容5</view>
</view>
</scroll-view>
</view> js文件:
Page({
data: {
scrollY: true,
fastDeceleration: true,
enhanced: true
}
}); css文件:
.scroll-view-item {
height: 100px;
background-color: aliceblue;
} hxml文件:
<view>
<scroll-view
class="flex-scroll-view"
scroll-y="{{scrollY}}"
enable-flex="{{enableFlex}}"
style="display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center">
<view id="{{'item-' + index}}" class="flex-item" has:for="{{itemCount}}" has:key="index">
{{index+1}}
</view>
</scroll-view>
</view> js文件:
Page({
data: {
scrollY: true,
enableFlex: true,
itemCount: 30
}
}); css文件:
.flex-scroll-view {
width: 100%;
height: 300px;
border: 1px solid #ccc;
margin-bottom: 20px;
}
.flex-item {
width: 75px;
height: 60px;
background: linear-gradient(135deg, #80d5cd 0%, #f19e9e 100%);
color: #ffffff;
text-align: center;
line-height: 60px;
margin: 5px;
border-radius: 10px;
flex-shrink: 0;
} hxml文件:
<view>
<scroll-view
style="width: 100%; height: 200px"
scroll-y="{{scrollY}}"
scroll-into-view="{{scrollIntoView}}"
scroll-into-view-offset="{{scrollIntoViewOffset}}">
<view>
<view class="scroll-view-item">列表内容1</view>
<view id="item2" class="scroll-view-item">列表内容2</view>
<view class="scroll-view-item">列表内容3</view>
<view class="scroll-view-item">列表内容4</view>
</view>
</scroll-view>
</view> js文件:
Page({
data: {
scrollY: true,
scrollIntoView: '',
scrollIntoViewOffset: 50
},
onLoad() {
setTimeout(() => {
this.setData({
scrollIntoView: 'item2'
});
}, 2000);
}
}); css文件:
.scroll-view-item {
height: 100px;
background-color: aliceblue;
} hxml文件:
<view>
<scroll-view
style="width: 100%; height: 200px"
scroll-y="{{scrollY}}"
paging-enabled="{{pagingEnabled}}"
enhanced="{{enhanced}}">
<view>
<view class="scroll-view-item">第一页</view>
<view class="scroll-view-item">第二页</view>
<view class="scroll-view-item">第三页</view>
<view class="scroll-view-item">第四页</view>
</view>
</scroll-view>
</view> js文件:
Page({
data: {
scrollY: true,
pagingEnabled: true,
enhanced: true
}
}); css文件:
.scroll-view-item {
height: 200px;
background-color: aliceblue;
} hxml文件:
<view>
<scroll-view
style="width: 100%; height: 300px"
scroll-y="{{scrollY}}"
using-sticky="{{usingSticky}}">
<view>
<view id="item1" class="scroll-view-item">列表内容1</view>
<view id="item2" class="scroll-view-item">列表内容2</view>
<view id="item3" class="scroll-view-item">列表内容3</view>
<view id="item4" class="scroll-view-item">列表内容4</view>
<view id="item5" class="scroll-view-item">列表内容5</view>
<view id="item6" class="scroll-view-item">列表内容6</view>
<view id="item7" class="scroll-view-item">列表内容7</view>
</view>
</scroll-view>
</view> js文件:
Page({
data: {
scrollY: true,
usingSticky: true
}
}); css文件:
.scroll-view-item {
height: 100px;
background-color: aliceblue;
}
#item2 {
position: sticky;
top: 0;
background-color: #fee2e2;
}
#item4 {
position: sticky;
bottom: 0;
background-color: #fee2e2;
}