1 | import { ComponentType } from 'react'
|
2 | import { BaseEventOrigFunction, CommonEventFunction, StandardProps } from './common'
|
3 | interface ScrollViewProps extends StandardProps {
|
4 | /** 允许横向滚动
|
5 | * @default false
|
6 | * @supported weapp, alipay, swan, tt, qq, jd, h5, rn, harmony, harmony_hybrid
|
7 | * @rn 二选一
|
8 | */
|
9 | scrollX?: boolean
|
10 | /** 允许纵向滚动
|
11 | * @default false
|
12 | * @supported weapp, alipay, swan, tt, qq, jd, h5, rn, harmony, harmony_hybrid
|
13 | * @rn 二选一
|
14 | */
|
15 | scrollY?: boolean
|
16 | /** 距顶部/左边多远时(单位px),触发 scrolltoupper 事件
|
17 | * @default 50
|
18 | * @supported weapp, alipay, swan, tt, qq, jd, h5, rn, harmony_hybrid
|
19 | */
|
20 | upperThreshold?: number
|
21 | /** 距底部/右边多远时(单位px),触发 scrolltolower 事件
|
22 | * @default 50
|
23 | * @supported weapp, alipay, swan, tt, qq, jd, h5, rn, harmony_hybrid
|
24 | */
|
25 | lowerThreshold?: number
|
26 | /** 设置竖向滚动条位置
|
27 | * @supported weapp, alipay, swan, tt, qq, jd, h5, rn, harmony_hybrid
|
28 | */
|
29 | scrollTop?: number
|
30 | /** 设置横向滚动条位置
|
31 | * @supported weapp, alipay, swan, tt, qq, jd, h5, rn, harmony_hybrid
|
32 | */
|
33 | scrollLeft?: number
|
34 | /** 值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素
|
35 | * @supported weapp, alipay, swan, tt, qq, jd, h5, harmony_hybrid
|
36 | */
|
37 | scrollIntoView?: string
|
38 | /** 在设置滚动条位置时使用动画过渡
|
39 | * @supported weapp, alipay, swan, tt, qq, jd, h5, rn, harmony_hybrid
|
40 | * @default false
|
41 | */
|
42 | scrollWithAnimation?: boolean
|
43 | /** iOS 点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只支持竖向
|
44 | * @supported weapp, alipay, swan, qq, jd, rn
|
45 | * @default false
|
46 | */
|
47 | enableBackToTop?: boolean
|
48 | /** 启用 flexbox 布局。开启后,当前节点声明了 `display: flex` 就会成为 flex container,并作用于其孩子节点。
|
49 | * @supported weapp, jd
|
50 | * @default false
|
51 | */
|
52 | enableFlex?: boolean
|
53 | /** 开启 scroll anchoring 特性,即控制滚动位置不随内容变化而抖动,仅在 iOS 下生效,安卓下可参考 CSS `overflow-anchor` 属性。
|
54 | * @supported weapp
|
55 | * @default false
|
56 | */
|
57 | scrollAnchoring?: boolean
|
58 | /** 开启自定义下拉刷新
|
59 | * @supported weapp
|
60 | * @default false
|
61 | */
|
62 | refresherEnabled?: boolean
|
63 | /** 设置自定义下拉刷新阈值
|
64 | * @supported weapp
|
65 | * @default 45
|
66 | */
|
67 | refresherThreshold?: number
|
68 | /** 设置自定义下拉刷新默认样式,支持设置 `black | white | none`, none 表示不使用默认样式
|
69 | * @supported weapp
|
70 | * @default 'black'
|
71 | */
|
72 | refresherDefaultStyle?: string
|
73 | /** 设置自定义下拉刷新区域背景颜色
|
74 | * @supported weapp
|
75 | * @default '#FFF'
|
76 | */
|
77 | refresherBackground?: string
|
78 | /** 设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发
|
79 | * @supported weapp
|
80 | * @default false
|
81 | */
|
82 | refresherTriggered?: boolean
|
83 | /** 启用 scroll-view 增强特性
|
84 | * @supported weapp, swan
|
85 | * @default false
|
86 | */
|
87 | enhanced?: boolean
|
88 | /** 使 scroll-view 下的 position sticky 特性生效,否则滚动一屏后 sticky 元素会被隐藏
|
89 | * @supported weapp
|
90 | * @default false
|
91 | */
|
92 | usingSticky?: boolean
|
93 | /** iOS 下 scroll-view 边界弹性控制 (同时开启 enhanced 属性后生效)
|
94 | * @supported weapp, swan
|
95 | * @default true
|
96 | */
|
97 | bounces?: boolean
|
98 | /** 滚动条显隐控制 (同时开启 enhanced 属性后生效)
|
99 | * @supported weapp, harmony
|
100 | * @default true
|
101 | */
|
102 | showScrollbar?: boolean
|
103 | /** 分页滑动效果 (同时开启 enhanced 属性后生效)
|
104 | * @supported weapp
|
105 | * @default false
|
106 | */
|
107 | pagingEnabled?: boolean
|
108 | /** boolean false 滑动减速速率控制 (同时开启 enhanced 属性后生效)
|
109 | * @supported weapp
|
110 | * @default false
|
111 | */
|
112 | fastDeceleration?: boolean
|
113 | /** 当 scroll-with-animation设置为 true 时,可以设置 scroll-animation-duration 来控制动画的执行时间,单位 ms。
|
114 | * @supported alipay
|
115 | */
|
116 | scrollAnimationDuration?: string
|
117 | /** 纵向滚动时,当滚动到顶部或底部时,强制禁止触发页面滚动,仍然只触发 scroll-view 自身的滚动。
|
118 | * @supported alipay
|
119 | * @default false
|
120 | */
|
121 | trapScroll?: string
|
122 | /** 发生滚动前,对滚动方向进行判断,当方向是顶部/左边时,如果值为 always 将始终禁止滚动,如果值为 out-of-bounds 且当前已经滚动到顶部/左边,禁止滚动。
|
123 | * @supported alipay
|
124 | */
|
125 | disableLowerScroll?: string
|
126 | /** 发生滚动前,对滚动方向进行判断,当方向是底部/右边时,如果值为 always 将始终禁止滚动,如果值为 out-of-bounds 且当前已经滚动到底部/右边,禁止滚动。
|
127 | * @supported alipay
|
128 | */
|
129 | disableUpperScroll?: string
|
130 | /** 无障碍访问,(属性)元素的额外描述
|
131 | * @supported qq
|
132 | */
|
133 | ariaLabel?: string
|
134 | /** 开启 passive 特性,能优化一定的滚动性能
|
135 | * @supported weapp
|
136 | * @default false
|
137 | */
|
138 | enablePassive?: boolean
|
139 | /** 渲染模式
|
140 | * list - 列表模式。只会渲染在屏节点,会根据直接子节点是否在屏来按需渲染,若只有一个直接子节点则性能会退化
|
141 | * custom - 自定义模式。只会渲染在屏节点,子节点可以是 sticky-section list-view grid-view 等组件
|
142 | * nested - 嵌套模式。用于处理父子 scroll-view 间的嵌套滚动,子节点可以是 nested-scroll-header nested-scroll-body 组件或自定义 refresher
|
143 | * @supported weapp, harmony
|
144 | * @default 'list'
|
145 | */
|
146 | type?: 'list' | 'custom' | 'nested'
|
147 | /** 是否反向滚动。一般初始滚动位置是在顶部,反向滚动则是在底部。
|
148 | * @supported weapp
|
149 | * @default false
|
150 | */
|
151 | reverse?: boolean
|
152 | /** 是否对溢出进行裁剪,默认开启
|
153 | * @supported weapp
|
154 | * @default true
|
155 | */
|
156 | clip?: boolean
|
157 | /** 指定视口外渲染区域的距离,默认情况下视口外节点不渲染。指定 cache-extent 可优化滚动体验和加载速度,但会提高内存占用且影响首屏速度,可按需启用。
|
158 | * @supported weapp
|
159 | */
|
160 | cacheExtent?: number
|
161 | /** 指定 scroll-view 触发滚动的最小拖动距离。仅在 scroll-view 和其他组件存在手势冲突时使用,可通过调整该属性使得滚动更加灵敏。
|
162 | * @supported weapp
|
163 | * @default 18
|
164 | */
|
165 | minDragDistance?: number
|
166 | /** 长度为 4 的数组,按 top、right、bottom、left 顺序指定内边距
|
167 | * @supported weapp
|
168 | * @default [0,0,0,0]
|
169 | */
|
170 | padding?: [number, number, number, number]
|
171 | /** 只 scroll-into-view 到 cacheExtent 以内的目标节点,性能更佳
|
172 | * @supported weapp
|
173 | * @default false
|
174 | */
|
175 | scrollIntoViewWithinExtent?: boolean
|
176 | /** 指定 scroll-into-view 目标节点在视口内的位置。
|
177 | * start - 目标节点显示在视口开始处
|
178 | * center - 目标节点显示在视口中间
|
179 | * end - 目标节点显示在视口结束处
|
180 | * nearest - 目标节点在就近的视口边缘显示,若节点已在视口内则不触发滚动
|
181 | * @supported weapp, h5, harmony_hybrid
|
182 | * @default 'start'
|
183 | */
|
184 | scrollIntoViewAlignment?: 'start' | 'center' | 'end' | 'nearest'
|
185 | /** 开启下拉二级能力
|
186 | * @supported weapp
|
187 | * @default false
|
188 | */
|
189 | refresherTwoLevelEnabled?: boolean
|
190 | /** 设置打开/关闭二级
|
191 | * @supported weapp
|
192 | * @default false
|
193 | */
|
194 | refresherTwoLevelTriggered?: boolean
|
195 | /** 下拉二级阈值
|
196 | * @supported weapp
|
197 | * @default 150
|
198 | */
|
199 | refresherTwoLevelThreshold?: number
|
200 | /** 滑动返回时关闭二级的阈值
|
201 | * @supported weapp
|
202 | * @default 80
|
203 | */
|
204 | refresherTwoLevelCloseThreshold?: number
|
205 | /** 处于二级状态时是否可滑动
|
206 | * @supported weapp
|
207 | * @default false
|
208 | */
|
209 | refresherTwoLevelScrollEnabled?: boolean
|
210 | /** 惯性滚动是否触发下拉刷新
|
211 | * @supported weapp
|
212 | * @default false
|
213 | */
|
214 | refresherBallisticRefreshEnabled?: boolean
|
215 | /** 即将打开二级时否定住
|
216 | * @supported weapp
|
217 | * @default false
|
218 | */
|
219 | refresherTwoLevelPinned?: boolean
|
220 | /** 滚动到顶部/左边,会触发 scrolltoupper 事件
|
221 | * @supported weapp, alipay, swan, tt, qq, jd, h5, rn, harmony_hybrid
|
222 | */
|
223 | onScrollToUpper?: CommonEventFunction
|
224 | /** 滚动到底部/右边,会触发 scrolltolower 事件
|
225 | * @supported weapp, alipay, swan, tt, qq, jd, h5, rn, harmony_hybrid
|
226 | */
|
227 | onScrollToLower?: CommonEventFunction
|
228 | /** 滚动时触发
|
229 | * @supported weapp, alipay, swan, tt, qq, jd, h5, rn, harmony, harmony_hybrid
|
230 | */
|
231 | onScroll?: BaseEventOrigFunction<ScrollViewProps.onScrollDetail>
|
232 | /** 滚动开始事件
|
233 | * @supported weapp
|
234 | */
|
235 | onScrollStart?: BaseEventOrigFunction<ScrollViewProps.onScrollDetail>
|
236 | /** 滚动结束事件
|
237 | * @supported weapp
|
238 | */
|
239 | onScrollEnd?: BaseEventOrigFunction<ScrollViewProps.onScrollDetail>
|
240 | /** 自定义下拉刷新控件被下拉
|
241 | * @supported weapp
|
242 | */
|
243 | onRefresherPulling?: CommonEventFunction
|
244 | /** 自定义下拉刷新被触发
|
245 | * @supported weapp
|
246 | */
|
247 | onRefresherRefresh?: CommonEventFunction
|
248 | /** 自定义下拉刷新被复位
|
249 | * @supported weapp
|
250 | */
|
251 | onRefresherRestore?: CommonEventFunction
|
252 | /** 自定义下拉刷新被中止
|
253 | * @supported weapp
|
254 | */
|
255 | onRefresherAbort?: CommonEventFunction
|
256 | /** 自定义下拉刷新即将触发刷新(拖动超过 refresher-threshold 时)的事件
|
257 | * @supported weapp
|
258 | */
|
259 | onRefresherWillRefresh?: CommonEventFunction
|
260 | /** 下拉刷新状态回调
|
261 | * @supported weapp
|
262 | */
|
263 | onRefresherStatusChange?: CommonEventFunction<ScrollViewProps.RefresherStatusChange>
|
264 | /** 滑动开始事件 (同时开启 enhanced 属性后生效)
|
265 | * @supported weapp
|
266 | */
|
267 | onDragStart?: CommonEventFunction<ScrollViewProps.onDragDetail>
|
268 | /** 滑动事件 (同时开启 enhanced 属性后生效)
|
269 | * @supported weapp
|
270 | */
|
271 | onDragging?: CommonEventFunction<ScrollViewProps.onDragDetail>
|
272 | /** 滑动结束事件 (同时开启 enhanced 属性后生效)
|
273 | * @supported weapp
|
274 | */
|
275 | onDragEnd?: CommonEventFunction<ScrollViewProps.onDragDetail>
|
276 | /** 触摸动作开始。
|
277 | * @supported alipay
|
278 | */
|
279 | onTouchStart?: CommonEventFunction
|
280 | /** 触摸后移动。
|
281 | * @supported alipay
|
282 | */
|
283 | onTouchMove?: CommonEventFunction
|
284 | /** 触摸动作结束。
|
285 | * @supported alipay
|
286 | */
|
287 | onTouchEnd?: CommonEventFunction
|
288 | /** 触摸动作被打断,如来电提醒、弹窗。
|
289 | * @supported alipay
|
290 | */
|
291 | onTouchCancel?: CommonEventFunction
|
292 | }
|
293 | declare namespace ScrollViewProps {
|
294 | interface onScrollDetail {
|
295 | /** 横向滚动条位置 */
|
296 | scrollLeft: number
|
297 | /** 竖向滚动条位置 */
|
298 | scrollTop: number
|
299 | /** 滚动条高度 */
|
300 | scrollHeight: number
|
301 | /** 滚动条宽度 */
|
302 | scrollWidth: number
|
303 | deltaX: number
|
304 | deltaY: number
|
305 | isDrag?: boolean
|
306 | }
|
307 | interface onDragDetail {
|
308 | /** 横向滚动条位置 */
|
309 | scrollLeft: number
|
310 | /** 竖向滚动条位置 */
|
311 | scrollTop: number
|
312 | /** 滚动速度 */
|
313 | velocity: number
|
314 | }
|
315 | interface RefresherStatusChange {
|
316 | status: RefreshStatus
|
317 | dy: number
|
318 | }
|
319 | const enum RefreshStatus {
|
320 | // 空闲
|
321 | Idle,
|
322 | // 超过下拉刷新阈值,同 bind:refresherwillRefresh 触发时机
|
323 | CanRefresh,
|
324 | // 下拉刷新,同 bind:refresherrefresh 触发时机
|
325 | Refreshing,
|
326 | // 下拉刷新完成,同 bind:refresherrestore 触发时机
|
327 | Completed,
|
328 | // 下拉刷新失败
|
329 | Failed,
|
330 | // 超过下拉二级阈值
|
331 | CanTwoLevel,
|
332 | // 开始打开二级
|
333 | TwoLevelOpening,
|
334 | // 打开二级
|
335 | TwoLeveling,
|
336 | // 开始关闭二级
|
337 | TwoLevelClosing,
|
338 | }
|
339 | }
|
340 | /** 可滚动视图区域。使用竖向滚动时,需要给scroll-view一个固定高度,通过 WXSS 设置 height。组件属性的长度单位默认为 px
|
341 | *
|
342 | * Tips:
|
343 | * H5 中 ScrollView 组件是通过一个高度(或宽度)固定的容器内部滚动来实现的,因此务必正确的设置容器的高度。例如: 如果 ScrollView 的高度将 body 撑开,就会同时存在两个滚动条(body 下的滚动条,以及 ScrollView 的滚动条)。
|
344 | * 微信小程序 中 ScrollView 组件如果设置 scrollX 横向滚动时,并且子元素为多个时(单个子元素时设置固定宽度则可以正常横向滚动),需要通过 WXSS 设置 `white-space: nowrap` 来保证元素不换行,并对 ScrollView 内部元素设置 `display: inline-block` 来使其能够横向滚动。
|
345 | * @classification viewContainer
|
346 | * @supported weapp, alipay, swan, tt, qq, jd, h5, rn, harmony, harmony_hybrid
|
347 | * @example_react
|
348 | * ```tsx
|
349 | * export default class PageView extends Component {
|
350 | * constructor() {
|
351 | * super(...arguments)
|
352 | * }
|
353 | *
|
354 | * onScrollToUpper() {}
|
355 | *
|
356 | * // or 使用箭头函数
|
357 | * // onScrollToUpper = () => {}
|
358 | *
|
359 | * onScroll(e){
|
360 | * console.log(e.detail)
|
361 | * }
|
362 | *
|
363 | * render() {
|
364 | * const scrollStyle = {
|
365 | * height: '150px'
|
366 | * }
|
367 | * const scrollTop = 0
|
368 | * const Threshold = 20
|
369 | * const vStyleA = {
|
370 | * height: '150px',
|
371 | * 'backgroundColor': 'rgb(26, 173, 25)'
|
372 | * }
|
373 | * const vStyleB = {
|
374 | * height: '150px',
|
375 | * 'backgroundColor': 'rgb(39,130,215)'
|
376 | * }
|
377 | * const vStyleC = {
|
378 | * height: '150px',
|
379 | * 'backgroundColor': 'rgb(241,241,241)',
|
380 | * color: '#333'
|
381 | * }
|
382 | * return (
|
383 | * <ScrollView
|
384 | * className='scrollview'
|
385 | * scrollY
|
386 | * scrollWithAnimation
|
387 | * scrollTop={scrollTop}
|
388 | * style={scrollStyle}
|
389 | * lowerThreshold={Threshold}
|
390 | * upperThreshold={Threshold}
|
391 | * onScrollToUpper={this.onScrollToUpper.bind(this)} // 使用箭头函数的时候 可以这样写 `onScrollToUpper={this.onScrollToUpper}`
|
392 | * onScroll={this.onScroll}
|
393 | * >
|
394 | * <View style={vStyleA}>A</View>
|
395 | * <View style={vStyleB}>B</View>
|
396 | * <View style={vStyleC}>C</View>
|
397 | * </ScrollView>
|
398 | * )
|
399 | * }
|
400 | * }
|
401 | * ```
|
402 | * @example_vue
|
403 | * ```html
|
404 | * <template>
|
405 | * <view class="container">
|
406 | * <view class="page-body">
|
407 | * <view class="page-section">
|
408 | * <view class="page-section-title">
|
409 | * <text>Vertical Scroll - 纵向滚动</text>
|
410 | * </view>
|
411 | * <view class="page-section-spacing">
|
412 | * <scroll-view :scroll-y="true" style="height: 300rpx;" `@scrolltoupper="upper" `@scrolltolower="lower" `@scroll="scroll" :scroll-into-view="toView" :scroll-top="scrollTop">
|
413 | * <view id="demo1" class="scroll-view-item demo-text-1">1</view>
|
414 | * <view id="demo2" class="scroll-view-item demo-text-2">2</view>
|
415 | * <view id="demo3" class="scroll-view-item demo-text-3">3</view>
|
416 | * </scroll-view>
|
417 | * </view>
|
418 | * </view>
|
419 | * <view class="page-section">
|
420 | * <view class="page-section-title">
|
421 | * <text>Horizontal Scroll - 横向滚动</text>
|
422 | * </view>
|
423 | * <view class="page-section-spacing">
|
424 | * <scroll-view class="scroll-view_H" :scroll-x="true" `@scroll="scroll" style="width: 100%">
|
425 | * <view id="demo21" class="scroll-view-item_H demo-text-1">a</view>
|
426 | * <view id="demo22" class="scroll-view-item_H demo-text-2">b</view>
|
427 | * <view id="demo23" class="scroll-view-item_H demo-text-3">c</view>
|
428 | * </scroll-view>
|
429 | * </view>
|
430 | * </view>
|
431 | * </view>
|
432 | * </view>
|
433 | * </template>
|
434 | *
|
435 | * <script>
|
436 | * const order = ['demo1', 'demo2', 'demo3']
|
437 | * export default {
|
438 | * name: 'Index',
|
439 | * data() {
|
440 | * return {
|
441 | * scrollTop: 0,
|
442 | * toView: 'demo2'
|
443 | * }
|
444 | * },
|
445 | *
|
446 | * methods: {
|
447 | * upper(e) {
|
448 | * console.log('upper:', e)
|
449 | * },
|
450 | *
|
451 | * lower(e) {
|
452 | * console.log('lower:', e)
|
453 | * },
|
454 | *
|
455 | * scroll(e) {
|
456 | * console.log('scroll:', e)
|
457 | * }
|
458 | * }
|
459 | * }
|
460 | * </script>
|
461 | *
|
462 | * <style>
|
463 | * .page-section-spacing{
|
464 | * margin-top: 60rpx;
|
465 | * }
|
466 | * .scroll-view_H{
|
467 | * white-space: nowrap;
|
468 | * }
|
469 | * .scroll-view-item{
|
470 | * height: 300rpx;
|
471 | * }
|
472 | * .scroll-view-item_H{
|
473 | * display: inline-block;
|
474 | * width: 100%;
|
475 | * height: 300rpx;
|
476 | * }
|
477 | *
|
478 | * .demo-text-1 { background: #ccc; }
|
479 | * .demo-text-2 { background: #999; }
|
480 | * .demo-text-3 { background: #666; }
|
481 | * </style>
|
482 | * ```
|
483 | * @see https://developers.weixin.qq.com/miniprogram/dev/component/scroll-view.html
|
484 | */
|
485 | declare const ScrollView: ComponentType<ScrollViewProps>
|
486 | export { ScrollView, ScrollViewProps }
|