Scroller 滚动组件 3.0.0
滚动组件,用来提供滚动容器。
- 提供了横向滚动和纵向滚动。
- 提供了『下拉刷新』和『加载更多』功能。
- 提供了
transition
和requestAnimationFrame
两种实现滚动的方式。 - 提供了
transform
和position:absolute
两种实现位移的方式。
确定高度:Scroller
默认提供一个纵向滚动区域,该区域必须有一个确定的高度才能正常工作,因为它实际上就是将一系列不确定高度的子组件(div.scroller
)装进一个确定高度的容器(div.yo-scroller
)。实现确定高度的方式有很多种:flex,指定高度,position: absolute
等等。
内容容器:作为一个滚动组件,Scroller 会创建一个 div 作为滚动容器。如果 Scroller 的子元素只有一个,则会把这个子元素当做内容容器;否则,会创建一个 div 作为内容容器。
引用方式
import { Scroller } from '$yo-component';
// 如果你的项目中未使用最新的 ykit-config-yo 插件,可能无法使用上面这个语法糖
// 你仍然可以通过下面这种方式来引用
import Scroller from 'yo3/component/scroller';
基本用法
Scroller
默认提供一个纵向滚动区域。该区域必须是有高度的,你可以通过以下几种方式来实现:
1. 直接设置 Scroller
的高度
<Scroller style={{ height: '400px' }}>
<h1>这是内容区域</h1>
</Scroller>
2. 通过 flex
来设置高度
<div className="yo-flex">
<Scroller extraClass="flex">
<h1>这是内容区域</h1>
</Scroller>
</div>
3. 通过 position: absolute
来设置高度
<Scroller style={{ position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 }}>
<h1>这是内容区域</h1>
</Scroller>
当然,为了方便 Scroller 组件中内置了 yo-scroller-fullscreen
样式类,可以直接使用达到上面的效果:
<Scroller extraClass="yo-scroller-fullscreen">
<h1>这是内容区域</h1>
</Scroller>
横向滚动
Scroller
可以提供一个横向滚动区域,只需要将 scrollX
设置为 true
将 scrollY
设置为 false
即可。
<Scroller
scrollX={true}
scrollY={false}
>
<h1>这是内容区域</h1>
</Scroller>
下拉刷新和加载更多
Scroller
提供了下拉刷新和加载更多的功能,这两个功能只支持纵向滚动。这两个功能常常在 List
组件中使用,查看List组件中的用法。
1. 下拉刷新
- 功能:在滚动到
Scroller
顶部之后,继续滚动一段距离就会触发下拉刷新
功能。该功能可以用来刷新Scroller
中的内容。 - 使用:
- 设置
usePullRefresh
参数为true
; - 通过
onRefresh
方法监听触发刷新状态(即:变成加载中状态)的回调; - 调用
Scroller
实例的stopRefreshing
方法来停止加载中状态,该方法的第一个参数为一个bool
值,用来告诉Scroller
是否刷新成功。 如果为true
,会显示『加载成功』;如果为false
,会显示『加载失败』。
- 设置
<Scroller
ref="scroller"
extraClass="yo-scroller-fullscreen"
usePullRefresh={true}
onRefresh={() => {
// 刷新数据 start
// ...
// 刷新数据 end
this.refs.scroller.stopRefreshing(true); // 这个调用也可以放在异步操作的回调里之后
}}
>
<h1>这是内容区域</h1>
</Scroller>
2. 加载更多
- 功能:在滚动到
Scroller
底部之后,继续滚动一段距离就会触发加载更多
功能。该功能可以用来加载Scroller
中更多的内容,比如:查看详情。 - 使用:
- 设置
useLoadMore
参数为true
; - 通过
onLoad
方法监听触发加载状态(即:变成加载中状态)的回调; - 调用
Scroller
实例的stopLoading
方法来停止加载中状态,该方法的第一个参数为一个bool
值,用来告诉Scroller
后面是否还有更多数据。 如果为false
会显示『没有更多了...』。
- 设置
<Scroller
ref="scroller"
extraClass="yo-scroller-fullscreen"
useLoadMore={true}
onLoad={() => {
// 加载数据 start
// ...
// 加载数据 end
this.refs.scroller.stopLoading(true); // 这个调用也可以放在异步操作的回调里之后
}}
>
<h1>这是内容区域</h1>
</Scroller>
滚动特性
Scroller
不仅提供了滚动容器,也提供了相关的滚动特性。
- 禁止滚动:
disabled
- 弹性滚动:
bounce
滚动是否能够超出屏幕范围 - 惯性滚动:
momentum
在松手之后有一定的速度,是否能够继续滚动一段距离
<Scroller
disabled={false}
bounce={false}
momentum={false}
>
<h1>这是内容区域</h1>
</Scroller>
滚动到某一位置
Scroller
提供了 scrollTo(x, y, time)
方法来滚动到某个位置。
- x:横向目标位置
- y:纵向目标位置
- time:滚动动画时间,单位 ms,默认为 0
<Scroller ref="scroller">
<h1>这是内容区域</h1>
</Scroller>
this.refs.scroller.scrollTo(0, -100, 300);
监听滚动事件
Scroller
提供了 onScroll
方法来监听滚动事件。一旦设置了这个回调,会强制使用 requestAnimationFrame
来实现滚动动画(包括:回弹、惯性滚动和 scrollTo
方法的动画),即使设置 useTransition
属性为 true
。
这样会导致 Scroller
的性能变差,请谨慎使用。
<Scroller
onScroll={(evt) => {
console.log(evt.contentOffset.x); // 当前横向位移
console.log(evt.contentOffset.y); // 当前纵向位移
}}
>
<h1>这是内容区域</h1>
</Scroller>
extraClass { String } #
为组件根节点提供额外的class。
默认值: ''
containerExtraClass { String } #
为组件中的内容容器提供额外的class。
默认值: ''
containerExtraStyle { String } 3.0.6 #
为组件中的内容容器提供额外的style,主要用于横向滚动时,动态设置容器的宽度。
默认值: {}
contentOffset { {x: Number, y: Mumber} } #
组件中内容的初始位移,这个属性变化时,会重置内容的位移。
默认值: {x: 0, y: 0}
contentInset { Number } 3.0.13 #
内容区域周围的留白,目前仅支持 bottom。主要用于适配 iPhoneX,在下方留出一定间隙。有『加载更多』时,显示在『加载更多』的下方。可以通过设置背景色来改变留白的颜色。
默认值: {bottom:0}
stickyOffset { Number } 3.0.6 #
吸顶容器偏移,如果你希望吸顶容器不位于top:0的位置,可以修改这个属性。
默认值: 0
disabled { Bool } #
是否禁止滚动,默认允许滚动。
默认值: false
scrollX { Bool } #
是否开启横向滚动,默认关闭。
默认值: false
scrollY { Bool } #
是否开启纵向滚动,默认开启。
默认值: true
directionLockThreshold { Number } #
只允许单向滚动的时候,会根据这个阀值来判定响应哪个方向上的位移:某一方向位移减去另一个方向位移超过阀值,就会判定为这个方向的滚动。
一个常见的示例是:在一个纵向滚动的 Scroller 中嵌套一个横向滚动的 Scroller。此时,如果斜着(约45°)滚动,则内层的 Scroller 会先响应, 但是不会锁定,触摸事件会向冒泡到外层的 Scroller,导致外层的 Scroller 也会响应。此时将 directionLockThreshold 设置成 0,保证不管向哪个方向滚动, Scroller 都会锁定方向而不向外冒泡,就不会出现同时响应的问题了。
默认值: 5
momentum { Bool } #
是否允许惯性滚动。当设置为 true
,手指离开时,如果还有速度会继续滚动一段距离;当设置为 false
,手指离开时会立即停止滚动。
默认值: true
bounce { Bool } #
当滚动超出内容范围时,是否可以继续滚动一截。
默认值: true
bounceTime { Number } #
当弹性滚动一截之后,回到滚动范围内位置的时间,单位为毫秒(ms)。
默认值: 600
bounceEasing { Object } #
弹性回滚动画。
Scroller 提供了五种默认的动画函数:quadratic
, circular
, back
, bounce
, elastic
,可以通过 Scroller.ease.xxx
来使用。
用户也可以自定义动画对象,比如:
{
style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
fn: function (k) {
return k * ( 2 - k );
}
}
默认值: Scroller.ease.circular
useTransition { Bool } #
如果设置为true,会使用transition来实现滚动效果;如果设置为false,会使用requestAnimationFrame来实现。
默认值: true
useTransform { Bool } #
如果设置为true,会使用transform来实现位移;如果设置为false,会使用left和top来实现位移(position: absolute)。
默认值: true
onScroll { Function } #
(event) => void
滚动事件的回调。一旦设置了这个回调,为了能够监听滚动事件,会将useTransition属性强制设置为false,会由此带来一定的性能牺牲。
方法参数:
参数名 | 类型 | 描述 | 支持版本 |
---|---|---|---|
event | e | 滚动事件的回调,结构为: {contentOffset: {x: x, y: y}} |
onScrollEnd { Function } #
(event) => void
滚动结束之后的回调。不管是不是 transition 的滚动,都会触发。
方法参数:
参数名 | 类型 | 描述 | 支持版本 |
---|---|---|---|
event | e | 滚动结束之后的回调,结构为: {contentOffset: {x: x, y: y}} |
HWCompositing { Bool } #
是否开启硬件加速
默认值: true
preventDefault { Bool } #
是否需要在Scroller容器上对所有的触摸事件(touchstart/touchmove/touchend/touchcancel)调用preventDefault。 这个属性的默认值为true,这是为了避免一些安卓的兼容性问题。如果你发现一些默认效果没有被触发(例如输入框的blur),可以尝试设置这个属性为false。
usePullRefresh { Bool } #
是否开启下拉刷新功能
默认值: false hasPullRefresh
onRefresh { Function } #
(event) => void
下拉刷新时开始刷新的回调。
方法参数:
参数名 | 类型 | 描述 | 支持版本 |
---|---|---|---|
event | e | 结构为: ({contentOffset: {x: x, y: y}}) |
pullRefreshHeight { Number } #
触发下拉刷新状态的高度(一般即为下拉刷新提示区域的高度)
默认值: 40 可以考虑不要
renderPullRefresh { Function } #
() => JSX
自定义的下拉刷新渲染函数
返回值: JSX 用来渲染
useLoadMore { Bool } #
是否开启加载更多功能.『加载更多』与『下拉刷新』略有不同,加载更多的提示区域是追加在内容区域的最后
默认值: false hasLoadMore
onLoad { Function } #
(event) => void
加载更多时开始加载的回调。
方法参数:
参数名 | 类型 | 描述 | 支持版本 |
---|---|---|---|
event | e | 结构为: ({contentOffset: {x: x, y: y}}) |
loadMoreHeight { Number } #
触发加载更多状态的高度(一般即为加载更多提示区域的高度)
默认值: 40
renderLoadMore { Function } #
() => JSX
自定义的加载更多渲染函数
返回值: JSX 用来渲染
scrollWithoutTouchStart { Bool } 3.0.2 #
实验中的属性 在默认情况下一次用户触发(非调用scrollTo方法)scroller的滚动需要由touchstart事件来启动,在某些情况下,例如scroller从disable状态切换到enable状态时, 可能不能接收到这一瞬间的touchstart事件,这可能导致用户期待的滚动过程没有发生。 开启这个属性为 true 以后将允许 scroller 用 touchmove 启动滚动过程,这可以解决上述场景的问题。
默认值: true (从 3.0.17 开始,默认值从 false 改为 true)
scrollIntoView { String } 3.1.7 #
值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素
默认值: ''
stopAnimate #
停止当前的滚动动画,包括:惯性滚动、回弹、ScrollTo等。
refresh #
刷新 Scroller,一般场景不推荐使用,因为当内容改变的时候,Scroller 会自动 render。
使用场景1:需要强制设置 Scroller 本身的宽高和内容容器的宽高时,可以通过refreshOption来传入宽高代替dom的宽高。
使用场景2:在某些不是通过 setState 或 Redux 等方式来改变内容导致 Scroller 不会 render 时,可以强制重新获取Scroller宽高和内容容器宽高。
方法参数:
参数名 | 类型 | 描述 | 必选 | 支持版本 |
---|---|---|---|---|
refreshOption | Object | 刷新参数,{wrapperWidth, wrapperHeight, scrollerWidth, scrollerHeight} |
refreshLazyImage 3.0.12 #
刷新 Scroller 中的 LazyImage。
使用场景:在某些不是通过 setState 或 Redux 等方式来直接改变 Scroller 的内容导致 Scroller 不会 render 时,由于内容宽高发生了变化,需要通过本方法来刷新 LazyImage 的位置信息。
scrollTo #
滚动到某个位置。
方法参数:
参数名 | 类型 | 描述 | 必选 | 支持版本 |
---|---|---|---|---|
x | Number | 水平位移,默认值为当前水平位移 | ||
y | Number | 垂直位移,默认值为当前垂直位移 | ||
time | Number | 滚动时间,默认值为0 | ||
easing | Object | 滚动动画对象。参照 `bounceEasing` 参数。 |
resetLoadStatus 3.0.7 #
重置加载更多功能。
方法参数:
参数名 | 类型 | 描述 | 必选 | 支持版本 |
---|---|---|---|---|
hasLoadMore | Bool | 是否能够加载更多,如果传入false,加载更多区域的文字将会变成 没有更多了,并且继续向下滚动时不会触发onLoadMore。 |
startRefreshing #
强制开始刷新。这个方法一般是用在切换筛选项或者关键字等场景,来达到回到顶部并且开始刷新的效果。如果是用户下拉触发 onRefresh
时,就不需要再调用这个方法了。
方法参数:
参数名 | 类型 | 描述 | 必选 | 支持版本 |
---|---|---|---|---|
time | Number | 滚动到顶部的时间,默认为 300ms |
stopRefreshing #
中止下拉刷新过程。在列表发生下拉刷新之后你应该调用这个方法去中止它(比如服务器响应已经返回的时候),否则刷新不会自动终止。
方法参数:
参数名 | 类型 | 描述 | 必选 | 支持版本 |
---|---|---|---|---|
success | Bool | 下拉刷新是否成功,默认为 false。 | ||
config | Object | 停止刷新的配置项
{
duration: |
||
config.duration | number | 回到顶部的动画时间,默认是 300ms。 | ||
config.delay | number | 成功/失败提示信息的停留时间,默认是0ms | 3.1.8 | |
callback | Function | 回到顶部的动画执行完毕的回调。 |
stopLoading #
停止加载更多。
方法参数:
参数名 | 类型 | 描述 | 必选 | 支持版本 |
---|---|---|---|---|
status | Bool | 刷新的状态。true表示加载了更多数据,false表示没有更多数据了。 |