@tarojs/components-advanced 4.1.12-beta.15 → 4.1.12-beta.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/water-flow/root.d.ts +22 -5
- package/dist/components/water-flow/root.js +49 -19
- package/dist/components/water-flow/root.js.map +1 -1
- package/dist/components/water-flow/section.d.ts +6 -0
- package/dist/components/water-flow/section.js +42 -5
- package/dist/components/water-flow/section.js.map +1 -1
- package/dist/components/water-flow/water-flow-node-cache.d.ts +24 -0
- package/dist/components/water-flow/water-flow-node-cache.js +134 -0
- package/dist/components/water-flow/water-flow-node-cache.js.map +1 -0
- package/dist/components/water-flow/water-flow.js +29 -4
- package/dist/components/water-flow/water-flow.js.map +1 -1
- package/package.json +9 -9
|
@@ -55,9 +55,17 @@ export declare class Root extends StatefulEventBus<RootState, Events> {
|
|
|
55
55
|
*/
|
|
56
56
|
sections: Section[];
|
|
57
57
|
/**
|
|
58
|
-
* 设置预加载的 Item
|
|
58
|
+
* 设置预加载的 Item 条数(与 props.cacheCount 一致,收敛目标)。
|
|
59
59
|
*/
|
|
60
60
|
cacheCount: number;
|
|
61
|
+
/**
|
|
62
|
+
* Node 层向上(列索引减小方向)预缓存条数,可与 cacheCount 不同(快速滑动单边放大)。
|
|
63
|
+
*/
|
|
64
|
+
nodeCacheBackward: number;
|
|
65
|
+
/**
|
|
66
|
+
* Node 层向下(列索引增大方向)预缓存条数。
|
|
67
|
+
*/
|
|
68
|
+
nodeCacheForward: number;
|
|
61
69
|
upperThresholdCount: number;
|
|
62
70
|
lowerThresholdCount: number;
|
|
63
71
|
/**
|
|
@@ -74,7 +82,7 @@ export declare class Root extends StatefulEventBus<RootState, Events> {
|
|
|
74
82
|
private _inUpperZone;
|
|
75
83
|
/** 当前是否处于触底区域;初始为 false */
|
|
76
84
|
private _inLowerZone;
|
|
77
|
-
/** scrollHeight
|
|
85
|
+
/** scrollHeight 更新防抖(raf),减轻 pushNodes 后测量前后的高度跳变 */
|
|
78
86
|
private _scrollHeightRafId;
|
|
79
87
|
constructor(props: RootProps);
|
|
80
88
|
/**
|
|
@@ -108,6 +116,12 @@ export declare class Root extends StatefulEventBus<RootState, Events> {
|
|
|
108
116
|
* scrollElement 模式:scrollOffset 为内容内偏移(scrollTop - startOffset),upper/lowerThresholdScrollTop 基于本组件内容计算,触顶/触底以本 WaterFlow 内容为基准
|
|
109
117
|
*/
|
|
110
118
|
private handleReachThreshold;
|
|
119
|
+
/**
|
|
120
|
+
* 列表追加并完成 finalize 后调用:重置触底边沿状态(_inLowerZone),
|
|
121
|
+
* 使用户仍在底部时下一次滚动能再次触发 onScrollToLower,而不必先上滑再下滑。
|
|
122
|
+
* 不在此处同步调用 handleReachThreshold,避免仍在底部时立刻连发触底(与误触区分)。
|
|
123
|
+
*/
|
|
124
|
+
resetLowerReachEdgeAfterContentChange(): void;
|
|
111
125
|
/**
|
|
112
126
|
* 容器的滚动上边界
|
|
113
127
|
*/
|
|
@@ -125,9 +139,8 @@ export declare class Root extends StatefulEventBus<RootState, Events> {
|
|
|
125
139
|
*/
|
|
126
140
|
get sectionRange(): number[][];
|
|
127
141
|
/**
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* @param immediate 为 true 时立即执行,不防抖(pushNodes 调用,避免容器高度滞后导致往上抖动)
|
|
142
|
+
* 更新总滚动高度(各 Section 累计)。
|
|
143
|
+
* @param immediate true 时跳过 raf 防抖(如 finalizePushNodesStateIfNeeded),避免高度滞后引起跳动
|
|
131
144
|
*/
|
|
132
145
|
updateScrollHeight(immediate?: boolean): void;
|
|
133
146
|
/**
|
|
@@ -146,6 +159,10 @@ export declare class Root extends StatefulEventBus<RootState, Events> {
|
|
|
146
159
|
* 查找节点
|
|
147
160
|
*/
|
|
148
161
|
findNode(id: string): Node;
|
|
162
|
+
/**
|
|
163
|
+
* 设置 Node 层上下方向预缓存条数,并刷新可见分组内的列渲染区间。
|
|
164
|
+
*/
|
|
165
|
+
setNodeCacheRange(backward: number, forward: number): void;
|
|
149
166
|
/**
|
|
150
167
|
* 获取分组渲染区间
|
|
151
168
|
*/
|
|
@@ -44,9 +44,17 @@ class Root extends StatefulEventBus {
|
|
|
44
44
|
*/
|
|
45
45
|
this.sections = [];
|
|
46
46
|
/**
|
|
47
|
-
* 设置预加载的 Item
|
|
47
|
+
* 设置预加载的 Item 条数(与 props.cacheCount 一致,收敛目标)。
|
|
48
48
|
*/
|
|
49
49
|
this.cacheCount = 1;
|
|
50
|
+
/**
|
|
51
|
+
* Node 层向上(列索引减小方向)预缓存条数,可与 cacheCount 不同(快速滑动单边放大)。
|
|
52
|
+
*/
|
|
53
|
+
this.nodeCacheBackward = 1;
|
|
54
|
+
/**
|
|
55
|
+
* Node 层向下(列索引增大方向)预缓存条数。
|
|
56
|
+
*/
|
|
57
|
+
this.nodeCacheForward = 1;
|
|
50
58
|
this.upperThresholdCount = 0;
|
|
51
59
|
this.lowerThresholdCount = 0;
|
|
52
60
|
/**
|
|
@@ -63,7 +71,7 @@ class Root extends StatefulEventBus {
|
|
|
63
71
|
this._inUpperZone = true;
|
|
64
72
|
/** 当前是否处于触底区域;初始为 false */
|
|
65
73
|
this._inLowerZone = false;
|
|
66
|
-
/** scrollHeight
|
|
74
|
+
/** scrollHeight 更新防抖(raf),减轻 pushNodes 后测量前后的高度跳变 */
|
|
67
75
|
this._scrollHeightRafId = null;
|
|
68
76
|
Object.assign(this, {
|
|
69
77
|
id,
|
|
@@ -72,6 +80,8 @@ class Root extends StatefulEventBus {
|
|
|
72
80
|
upperThresholdCount,
|
|
73
81
|
skipContainerMeasure: !!skipContainerMeasure,
|
|
74
82
|
});
|
|
83
|
+
this.nodeCacheBackward = cacheCount;
|
|
84
|
+
this.nodeCacheForward = cacheCount;
|
|
75
85
|
this.setupSubscriptions();
|
|
76
86
|
if (!skipContainerMeasure) {
|
|
77
87
|
getRectSizeSync(`#${id}`, 100).then(({ width = windowWidth, height = windowHeight }) => {
|
|
@@ -87,22 +97,16 @@ class Root extends StatefulEventBus {
|
|
|
87
97
|
* 设置订阅事件
|
|
88
98
|
*/
|
|
89
99
|
setupSubscriptions() {
|
|
90
|
-
/**
|
|
91
|
-
* 滚动过程中计算渲染的分组区间
|
|
92
|
-
* 滚动过程中分组的最大高度会发生更新,可以在这时计算滚动高度
|
|
93
|
-
*/
|
|
94
|
-
this.sub('scrollOffset', () => {
|
|
95
|
-
this.setStateIn('renderRange', this.getSectionRenderRange());
|
|
96
|
-
this.handleReachThreshold();
|
|
97
|
-
this.updateScrollHeight();
|
|
98
|
-
});
|
|
100
|
+
/** 滚动:先更新触底阈值,再判触顶/触底并更新分组与总高度,避免同一帧内沿用无效阈值。 */
|
|
99
101
|
this.sub('scrollOffset', () => {
|
|
100
102
|
const sectionSize = this.sections.length;
|
|
101
103
|
const lastSection = this.sections[sectionSize - 1];
|
|
102
|
-
// 最后一个分组的每一列最后一行都已经完成了布局计算,那么这个时候的总高度应该是准确的
|
|
103
104
|
if (lastSection === null || lastSection === void 0 ? void 0 : lastSection.columnMap.every((column) => { var _a; return (_a = column[column.length - 1]) === null || _a === void 0 ? void 0 : _a.getState().layouted; })) {
|
|
104
105
|
this.setLowerThresholdScrollTop();
|
|
105
106
|
}
|
|
107
|
+
this.setStateIn('renderRange', this.getSectionRenderRange());
|
|
108
|
+
this.handleReachThreshold();
|
|
109
|
+
this.updateScrollHeight();
|
|
106
110
|
});
|
|
107
111
|
this.sub(RootEvents.AllSectionsLayouted, () => {
|
|
108
112
|
this.updateScrollHeight();
|
|
@@ -209,7 +213,9 @@ class Root extends StatefulEventBus {
|
|
|
209
213
|
// 必须用 sectionRange 实时计算,避免依赖可能未更新的 scrollHeight 状态
|
|
210
214
|
const range = this.sectionRange;
|
|
211
215
|
const totalHeight = range.length > 0 ? range[range.length - 1][1] : 0;
|
|
212
|
-
|
|
216
|
+
// 触底判定:scrollOffset + containerSize.height >= lowerThresholdScrollTop
|
|
217
|
+
// 须存内容底边 totalHeight(H)。若误存 H-h,则顶部时 h 与 H-h 比较,当 2h>=H 会恒判为在触底区,误触 onScrollToLower。
|
|
218
|
+
this.lowerThresholdScrollTop = totalHeight;
|
|
213
219
|
return 0;
|
|
214
220
|
}
|
|
215
221
|
const sectionSize = this.sections.length;
|
|
@@ -270,6 +276,14 @@ class Root extends StatefulEventBus {
|
|
|
270
276
|
this._inUpperZone = inUpper;
|
|
271
277
|
this._inLowerZone = inLower;
|
|
272
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* 列表追加并完成 finalize 后调用:重置触底边沿状态(_inLowerZone),
|
|
281
|
+
* 使用户仍在底部时下一次滚动能再次触发 onScrollToLower,而不必先上滑再下滑。
|
|
282
|
+
* 不在此处同步调用 handleReachThreshold,避免仍在底部时立刻连发触底(与误触区分)。
|
|
283
|
+
*/
|
|
284
|
+
resetLowerReachEdgeAfterContentChange() {
|
|
285
|
+
this._inLowerZone = false;
|
|
286
|
+
}
|
|
273
287
|
/**
|
|
274
288
|
* 容器的滚动上边界
|
|
275
289
|
*/
|
|
@@ -304,9 +318,8 @@ class Root extends StatefulEventBus {
|
|
|
304
318
|
return range;
|
|
305
319
|
}
|
|
306
320
|
/**
|
|
307
|
-
*
|
|
308
|
-
*
|
|
309
|
-
* @param immediate 为 true 时立即执行,不防抖(pushNodes 调用,避免容器高度滞后导致往上抖动)
|
|
321
|
+
* 更新总滚动高度(各 Section 累计)。
|
|
322
|
+
* @param immediate true 时跳过 raf 防抖(如 finalizePushNodesStateIfNeeded),避免高度滞后引起跳动
|
|
310
323
|
*/
|
|
311
324
|
updateScrollHeight(immediate = false) {
|
|
312
325
|
const flush = () => {
|
|
@@ -356,6 +369,23 @@ class Root extends StatefulEventBus {
|
|
|
356
369
|
findNode(id) {
|
|
357
370
|
return this.nodeMap.get(id);
|
|
358
371
|
}
|
|
372
|
+
/**
|
|
373
|
+
* 设置 Node 层上下方向预缓存条数,并刷新可见分组内的列渲染区间。
|
|
374
|
+
*/
|
|
375
|
+
setNodeCacheRange(backward, forward) {
|
|
376
|
+
const b = Math.max(0, Math.floor(backward));
|
|
377
|
+
const f = Math.max(0, Math.floor(forward));
|
|
378
|
+
if (this.nodeCacheBackward === b && this.nodeCacheForward === f) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
this.nodeCacheBackward = b;
|
|
382
|
+
this.nodeCacheForward = f;
|
|
383
|
+
for (const section of this.sections) {
|
|
384
|
+
if (section.isInRange) {
|
|
385
|
+
section.setStateIn('renderRange', section.getNodeRenderRange());
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
359
389
|
/**
|
|
360
390
|
* 获取分组渲染区间
|
|
361
391
|
*/
|
|
@@ -374,10 +404,10 @@ class Root extends StatefulEventBus {
|
|
|
374
404
|
if (result[1] === -Infinity) {
|
|
375
405
|
result[1] = this.sections.length - 1;
|
|
376
406
|
}
|
|
377
|
-
const scrollDirection = this.getState().scrollDirection;
|
|
378
407
|
const [backwardCache, forwardCache] = this.calcCacheSection(result);
|
|
379
|
-
|
|
380
|
-
const
|
|
408
|
+
// 双向预缓存,避免反向滚动时出现空白(原逻辑仅在滚动方向缓存,反向时未预渲染)
|
|
409
|
+
const backwardDistance = backwardCache;
|
|
410
|
+
const forwardDistance = forwardCache;
|
|
381
411
|
const overscanBackward = result[0] - backwardDistance;
|
|
382
412
|
const overscanForward = result[1] + forwardDistance;
|
|
383
413
|
result[0] = overscanBackward < 0 ? 0 : overscanBackward;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root.js","sources":["../../../src/components/water-flow/root.ts"],"sourcesContent":["/* eslint-disable no-labels */\nimport { cancelAnimationFrame, requestAnimationFrame } from '@tarojs/runtime'\nimport { nextTick } from '@tarojs/taro'\n\nimport { getRectSizeSync } from '../../utils'\nimport { Node } from './node'\nimport { Section } from './section'\nimport { StatefulEventBus } from './stateful-event-bus'\nimport { getSysInfo, isSameRenderRange } from './utils'\n\nimport type { BaseProps, ScrollDirection, Size, WaterFlowProps } from './interface'\n\nexport type RootProps = Pick<WaterFlowProps, 'cacheCount' | 'lowerThresholdCount' | 'upperThresholdCount'> &\nRequired<Pick<BaseProps, 'id'>> & {\n /** scrollElement 模式下为 true,不测量自有容器;此时需布局全部 section 以展开完整高度 */\n skipContainerMeasure?: boolean\n}\n\nconst { windowHeight, windowWidth } = getSysInfo()\n\ntype RootState = {\n /** 是否在滚动中 */\n isScrolling: boolean\n /** 滚动偏移量 */\n scrollOffset: number\n /**\n * 滚动方向\n *\n * - forward 向下滚动\n *\n * - backward 向上滚动\n */\n scrollDirection: ScrollDirection\n /** 滚动高度 */\n scrollHeight: number\n /** 容器的尺寸信息 */\n containerSize: Size\n /** 渲染的分组区间范围 */\n renderRange: [number, number]\n}\n\nexport const RootEvents = {\n ReachUpperThreshold: Symbol.for('ReachUpperThreshold'),\n ReachLowerThreshold: Symbol.for('ReachLowerThreshold'),\n Resize: Symbol.for('Resize'),\n AllSectionsLayouted: Symbol.for('AllSectionsLayouted'),\n InitialRenderCompleted: Symbol.for('InitialRenderCompleted'),\n}\n\ntype Events = keyof typeof RootEvents\n\n/**\n * 数据模型继承自有状态的事件总线,便于在节点之间通信,以及通过 useSyncExternalStore 关联 React 视图\n */\nexport class Root extends StatefulEventBus<RootState, Events> {\n /**\n * 瀑布流根节点唯一标识\n */\n id: string\n /**\n * 分组映射表,便于查找分组\n */\n sectionMap: Map<string, Section> = new Map()\n /**\n * 节点映射表,便于查找节点\n */\n nodeMap: Map<string, Node> = new Map()\n /**\n * 分组列表,基于计算出的渲染的分组区间范围 sections.slice(start, end + 1) 进行渲染\n */\n sections: Section[] = []\n /**\n * 设置预加载的 Item 条数。\n */\n cacheCount = 1\n\n upperThresholdCount = 0\n\n lowerThresholdCount = 0\n\n /**\n * 触发滚动阈值对应的 scrollTop 值\n */\n upperThresholdScrollTop = -Infinity\n\n /**\n * 触发滚动阈值对应的 scrollTop 值\n */\n lowerThresholdScrollTop = Infinity\n\n /** scrollElement 模式下为 true,需布局全部 section 以展开完整高度供父容器滚动 */\n skipContainerMeasure = false\n\n /** 当前是否处于触顶区域;初始为 true(起始在顶部),只有从 false→true 时才触发事件 */\n private _inUpperZone = true\n /** 当前是否处于触底区域;初始为 false */\n private _inLowerZone = false\n /** scrollHeight 防抖(raf),避免 pushNodes + 测量 导致的 先涨后跌 闪动 */\n private _scrollHeightRafId: number | null = null\n\n constructor(props: RootProps) {\n const { id, cacheCount, lowerThresholdCount, upperThresholdCount, skipContainerMeasure } = props\n super({\n isScrolling: false,\n scrollOffset: 0,\n scrollDirection: 'forward',\n scrollHeight: windowHeight,\n renderRange: [0, 0],\n containerSize: {\n width: windowWidth,\n height: windowHeight,\n },\n })\n Object.assign(this, {\n id,\n cacheCount,\n lowerThresholdCount,\n upperThresholdCount,\n skipContainerMeasure: !!skipContainerMeasure,\n })\n this.setupSubscriptions()\n if (!skipContainerMeasure) {\n getRectSizeSync(`#${id}`, 100).then(({ width = windowWidth, height = windowHeight }) => {\n this.setStateIn('containerSize', {\n width,\n height,\n })\n })\n }\n this.renderInitialLayout()\n }\n\n /**\n * 设置订阅事件\n */\n private setupSubscriptions() {\n /**\n * 滚动过程中计算渲染的分组区间\n * 滚动过程中分组的最大高度会发生更新,可以在这时计算滚动高度\n */\n this.sub('scrollOffset', () => {\n this.setStateIn('renderRange', this.getSectionRenderRange())\n this.handleReachThreshold()\n this.updateScrollHeight()\n })\n\n this.sub('scrollOffset', () => {\n const sectionSize = this.sections.length\n const lastSection = this.sections[sectionSize - 1]\n // 最后一个分组的每一列最后一行都已经完成了布局计算,那么这个时候的总高度应该是准确的\n if (lastSection?.columnMap.every((column) => column[column.length - 1]?.getState().layouted)) {\n this.setLowerThresholdScrollTop()\n }\n })\n\n this.sub(RootEvents.AllSectionsLayouted, () => {\n this.updateScrollHeight()\n this.setUpperThresholdScrollTop()\n this.setLowerThresholdScrollTop()\n })\n\n this.sub(RootEvents.Resize, () => {\n this.updateScrollHeight()\n this.setUpperThresholdScrollTop()\n this.setLowerThresholdScrollTop()\n })\n }\n\n /**\n * 渐进式渲染\n *\n * 因为初始没法知道每个分组的高度信息,不知道渲染边界,所以需要渐进式渲染\n *\n * 当目前的渲染批次的首个分组的scrollTop大于容器的高度,说明容器可视区域已经填满,没必要再往下渲染了\n *\n * @param [i=0] 从第几个分组开始渲染\n *\n */\n renderInitialLayout(i = 0) {\n nextTick(() => {\n const sectionSize = this.sections.length\n\n if (i >= sectionSize || i < 0) {\n this.pub(RootEvents.InitialRenderCompleted, null)\n return\n }\n const section = this.sections[i]\n section.layoutedSignal.promise.then(() => {\n this.setStateIn('renderRange', [0, i + 1 > sectionSize ? sectionSize - 1 : i + 1])\n // skipContainerMeasure(nestedScroll 模式):需布局全部 section,使 scrollHeight 展开供父容器滚动\n // default 模式:容器可视区域已填满则提前终止,减少首屏渲染\n if (\n !this.skipContainerMeasure &&\n section.getState().scrollTop > this.getState().containerSize.height\n ) {\n this.pub(RootEvents.InitialRenderCompleted, section)\n return\n }\n\n this.renderInitialLayout(i + 1)\n })\n })\n }\n\n /**\n * 计算滚动阈值对应的 scrollTop 并设置 upperThresholdScrollTop\n * 当距顶部还有 upperThresholdCount 个 FlowItem 时的 scrollTop 值\n */\n private setUpperThresholdScrollTop() {\n // 如果没有设置阈值或阈值为0,则返回0\n if (!this.upperThresholdCount) {\n this.upperThresholdScrollTop = 0\n return 0\n }\n const sectionSize = this.sections.length\n const tracker = Array.from(\n { length: sectionSize },\n () => new Map<number, { accCount: number, accHeight: number }>() // Map<列, { 当前列累计个数,当前列累计高度 }>\n )\n\n // 从第一个分组开始扫描\n loopSeciton: for (let i = 0; i < sectionSize; i++) {\n const section = this.sections[i]\n const sectionTracker = tracker[i]\n const columnMap = section.columnMap\n // 扫描当前分组的每一列\n for (let col = 0; col < columnMap.length; col++) {\n const column = columnMap[col]\n const columnSize = column.length\n if (!sectionTracker.has(col)) {\n if (i === 0) {\n sectionTracker.set(col, { accCount: 0, accHeight: 0 })\n } else {\n const previousSectionTracker = tracker[i - 1]\n sectionTracker.set(col, {\n accCount: Math.max(...[...previousSectionTracker.values()].map((nodeTracker) => nodeTracker.accCount)),\n accHeight: section.getState().scrollTop,\n })\n }\n }\n const colTracker = sectionTracker.get(col)!\n // 扫描当前列的每一行\n loopItem: for (let j = 0; j < columnSize; j++) {\n colTracker.accCount += 1\n colTracker.accHeight += column[j].getState().height + (j === 0 ? 0 : section.rowGap)\n if (colTracker.accCount >= this.upperThresholdCount) {\n break loopItem\n }\n }\n }\n for (const [, colTracker] of sectionTracker) {\n if (colTracker.accCount >= this.upperThresholdCount) {\n this.upperThresholdScrollTop = colTracker.accHeight\n break loopSeciton\n }\n }\n }\n return this.upperThresholdScrollTop\n }\n\n /**\n * 计算滚动阈值对应的 scrollTop 并设置 lowerThresholdScrollTop\n * 当距底部还有 lowerThresholdCount 个 FlowItem 时的 scrollTop 值\n */\n private setLowerThresholdScrollTop() {\n // 与 setUpperThresholdScrollTop 一致:0 或 undefined 时用「内容底 - 容器高」作为触底阈值\n if (!this.lowerThresholdCount) {\n // 必须用 sectionRange 实时计算,避免依赖可能未更新的 scrollHeight 状态\n const range = this.sectionRange\n const totalHeight = range.length > 0 ? range[range.length - 1][1] : 0\n this.lowerThresholdScrollTop = totalHeight - this.getState().containerSize.height\n return 0\n }\n const sectionSize = this.sections.length\n const tracker = Array.from(\n { length: sectionSize },\n () => new Map<number, { accCount: number, scrollTop: number }>()\n )\n // 从最后一个分组开始计算\n loopSeciton: for (let i = sectionSize - 1; i >= 0; i--) {\n const section = this.sections[i]\n const sectionTracker = tracker[i]\n const columnMap = section.columnMap\n // 扫描当前分组的每一列\n for (let col = 0; col < columnMap.length; col++) {\n const column = columnMap[col]\n const columnSize = column.length\n if (!sectionTracker.has(col)) {\n if (i === sectionSize - 1) {\n sectionTracker.set(col, { accCount: 0, scrollTop: 0 })\n } else {\n const belowSectionTracker = tracker[i + 1]\n sectionTracker.set(col, {\n accCount: Math.max(...[...belowSectionTracker.values()].map((nodeTracker) => nodeTracker.accCount)),\n scrollTop: 0,\n })\n }\n }\n const colTracker = sectionTracker.get(col)!\n // 从当前列的最后一行开始往前扫描\n loopItem: for (let j = columnSize - 1; j >= 0; j--) {\n colTracker.accCount += 1\n colTracker.scrollTop = column[j].getState().scrollTop\n if (colTracker.accCount >= this.lowerThresholdCount) {\n break loopItem\n }\n }\n }\n\n for (const [, colTracker] of sectionTracker) {\n if (colTracker.accCount >= this.lowerThresholdCount) {\n this.lowerThresholdScrollTop = colTracker.scrollTop\n break loopSeciton\n }\n }\n }\n\n return this.lowerThresholdScrollTop\n }\n\n /**\n * 处理滚动到阈值的情况\n * 检测当前滚动位置是否达到了上下阈值,并触发相应的事件\n * scrollElement 模式:scrollOffset 为内容内偏移(scrollTop - startOffset),upper/lowerThresholdScrollTop 基于本组件内容计算,触顶/触底以本 WaterFlow 内容为基准\n */\n private handleReachThreshold() {\n const { scrollOffset, containerSize } = this.getState()\n const inUpper = this.upperThresholdScrollTop !== -Infinity && scrollOffset <= this.upperThresholdScrollTop\n const inLower = this.lowerThresholdScrollTop !== Infinity && scrollOffset + containerSize.height >= this.lowerThresholdScrollTop\n if (inUpper && !this._inUpperZone) this.pub(RootEvents.ReachUpperThreshold)\n if (inLower && !this._inLowerZone) this.pub(RootEvents.ReachLowerThreshold)\n this._inUpperZone = inUpper\n this._inLowerZone = inLower\n }\n\n /**\n * 容器的滚动上边界\n */\n get scrollBoundaryStart() {\n return this.getState().scrollOffset\n }\n\n /**\n * 容器的滚动下边界\n */\n get scrollBoundaryEnd() {\n return this.scrollBoundaryStart + this.getStateIn('containerSize').height\n }\n\n /**\n * 计算每个section的底部位置\n *\n * sectionBottomRange = [ [section1.top, section1.bottom], [section2.top, section2.bottom], ..., [sectionN.top, sectionN.bottom] ]\n *\n * @returns [number,number][]\n */\n get sectionRange() {\n const length = this.sections.length\n if (length === 0) return []\n const range = Array.from({ length }, () => [0, this.sections[0].maxColumnHeight])\n for (let i = 1; i < length; i++) {\n const previous = range[i - 1]\n const prevSection = this.sections[i - 1]\n const gap = prevSection.rowGap ?? 0\n range[i] = [previous[1] + gap, previous[1] + gap + this.sections[i].maxColumnHeight]\n }\n\n return range\n }\n\n /**\n * 计算滚动高度\n * 防抖一帧(raf),避免 pushNodes 后测量完成前出现 先涨(未测量默认高度)后跌(真实高度)导致的闪动\n * @param immediate 为 true 时立即执行,不防抖(pushNodes 调用,避免容器高度滞后导致往上抖动)\n */\n public updateScrollHeight(immediate = false) {\n const flush = () => {\n const next = this.sectionRange[this.sectionRange.length - 1]?.[1] ?? 0\n this.setStateIn('scrollHeight', next)\n }\n if (immediate) {\n if (this._scrollHeightRafId != null) {\n cancelAnimationFrame(this._scrollHeightRafId)\n this._scrollHeightRafId = null\n }\n flush()\n return\n }\n if (this._scrollHeightRafId != null) {\n cancelAnimationFrame(this._scrollHeightRafId)\n }\n this._scrollHeightRafId = requestAnimationFrame(() => {\n this._scrollHeightRafId = null\n flush()\n })\n }\n\n /**\n * 注册分组\n */\n public registerSection(section: Section) {\n const { id, order } = section\n this.sectionMap.set(id, section)\n this.sections[order] = section\n }\n\n /**\n * 注册节点\n */\n public registerNode(node: Node) {\n this.nodeMap.set(node.id, node)\n }\n\n /**\n * 查找分组\n */\n public findSection(id: string) {\n return this.sectionMap.get(id)\n }\n\n /**\n * 查找节点\n */\n public findNode(id: string) {\n return this.nodeMap.get(id)\n }\n\n /**\n * 获取分组渲染区间\n */\n public getSectionRenderRange() {\n const result: [number, number] = [Infinity, -Infinity]\n\n for (let i = 0; i < this.sections.length; i++) {\n const section = this.sections[i]\n if (section.isInRange) {\n result[0] = Math.min(result[0], i)\n result[1] = Math.max(result[1], i)\n }\n }\n\n if (result[0] === Infinity) {\n result[0] = 0\n }\n\n if (result[1] === -Infinity) {\n result[1] = this.sections.length - 1\n }\n\n const scrollDirection = this.getState().scrollDirection\n const [backwardCache, forwardCache] = this.calcCacheSection(result)\n const backwardDistance = scrollDirection === 'backward' ? backwardCache : 0\n const forwardDistance = scrollDirection === 'forward' ? forwardCache : 0\n\n const overscanBackward = result[0] - backwardDistance\n const overscanForward = result[1] + forwardDistance\n\n result[0] = overscanBackward < 0 ? 0 : overscanBackward\n\n result[1] = overscanForward > this.sections.length ? this.sections.length - 1 : overscanForward\n\n const prevRange = this.getState().renderRange\n return isSameRenderRange(result, prevRange) ? prevRange : result\n }\n\n /**\n * 计算预渲染的分组个数\n */\n private calcCacheSection(renderRange: [number, number]) {\n const clientHeight = this.getState().containerSize.height\n const sectionCount = this.sectionMap.size\n let [start, end] = renderRange\n let cacheBackward = 1\n let cacheForward = 1\n\n if (start > 0) {\n let acc = this.sections[--start]?.getState().height ?? 0\n while (--start > 0) {\n const prevSection = this.sections[start]\n acc += prevSection.getState().height\n cacheBackward += 1\n if (acc >= clientHeight >>> 1) {\n break\n }\n }\n }\n\n if (end < sectionCount - 1) {\n let acc = this.sections[++end]?.getState().height ?? 0\n while (++end < sectionCount - 1) {\n const nextSection = this.sections[end]\n acc += nextSection.getState().height\n cacheForward += 1\n if (acc >= clientHeight >>> 1) {\n break\n }\n }\n }\n\n return [cacheBackward, cacheForward]\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"root.js","sources":["../../../src/components/water-flow/root.ts"],"sourcesContent":["/* eslint-disable no-labels */\nimport { cancelAnimationFrame, requestAnimationFrame } from '@tarojs/runtime'\nimport { nextTick } from '@tarojs/taro'\n\nimport { getRectSizeSync } from '../../utils'\nimport { Node } from './node'\nimport { Section } from './section'\nimport { StatefulEventBus } from './stateful-event-bus'\nimport { getSysInfo, isSameRenderRange } from './utils'\n\nimport type { BaseProps, ScrollDirection, Size, WaterFlowProps } from './interface'\n\nexport type RootProps = Pick<WaterFlowProps, 'cacheCount' | 'lowerThresholdCount' | 'upperThresholdCount'> &\nRequired<Pick<BaseProps, 'id'>> & {\n /** scrollElement 模式下为 true,不测量自有容器;此时需布局全部 section 以展开完整高度 */\n skipContainerMeasure?: boolean\n}\n\nconst { windowHeight, windowWidth } = getSysInfo()\n\ntype RootState = {\n /** 是否在滚动中 */\n isScrolling: boolean\n /** 滚动偏移量 */\n scrollOffset: number\n /**\n * 滚动方向\n *\n * - forward 向下滚动\n *\n * - backward 向上滚动\n */\n scrollDirection: ScrollDirection\n /** 滚动高度 */\n scrollHeight: number\n /** 容器的尺寸信息 */\n containerSize: Size\n /** 渲染的分组区间范围 */\n renderRange: [number, number]\n}\n\nexport const RootEvents = {\n ReachUpperThreshold: Symbol.for('ReachUpperThreshold'),\n ReachLowerThreshold: Symbol.for('ReachLowerThreshold'),\n Resize: Symbol.for('Resize'),\n AllSectionsLayouted: Symbol.for('AllSectionsLayouted'),\n InitialRenderCompleted: Symbol.for('InitialRenderCompleted'),\n}\n\ntype Events = keyof typeof RootEvents\n\n/**\n * 数据模型继承自有状态的事件总线,便于在节点之间通信,以及通过 useSyncExternalStore 关联 React 视图\n */\nexport class Root extends StatefulEventBus<RootState, Events> {\n /**\n * 瀑布流根节点唯一标识\n */\n id: string\n /**\n * 分组映射表,便于查找分组\n */\n sectionMap: Map<string, Section> = new Map()\n /**\n * 节点映射表,便于查找节点\n */\n nodeMap: Map<string, Node> = new Map()\n /**\n * 分组列表,基于计算出的渲染的分组区间范围 sections.slice(start, end + 1) 进行渲染\n */\n sections: Section[] = []\n /**\n * 设置预加载的 Item 条数(与 props.cacheCount 一致,收敛目标)。\n */\n cacheCount = 1\n\n /**\n * Node 层向上(列索引减小方向)预缓存条数,可与 cacheCount 不同(快速滑动单边放大)。\n */\n nodeCacheBackward = 1\n\n /**\n * Node 层向下(列索引增大方向)预缓存条数。\n */\n nodeCacheForward = 1\n\n upperThresholdCount = 0\n\n lowerThresholdCount = 0\n\n /**\n * 触发滚动阈值对应的 scrollTop 值\n */\n upperThresholdScrollTop = -Infinity\n\n /**\n * 触发滚动阈值对应的 scrollTop 值\n */\n lowerThresholdScrollTop = Infinity\n\n /** scrollElement 模式下为 true,需布局全部 section 以展开完整高度供父容器滚动 */\n skipContainerMeasure = false\n\n /** 当前是否处于触顶区域;初始为 true(起始在顶部),只有从 false→true 时才触发事件 */\n private _inUpperZone = true\n /** 当前是否处于触底区域;初始为 false */\n private _inLowerZone = false\n /** scrollHeight 更新防抖(raf),减轻 pushNodes 后测量前后的高度跳变 */\n private _scrollHeightRafId: number | null = null\n\n constructor(props: RootProps) {\n const { id, cacheCount, lowerThresholdCount, upperThresholdCount, skipContainerMeasure } = props\n super({\n isScrolling: false,\n scrollOffset: 0,\n scrollDirection: 'forward',\n scrollHeight: windowHeight,\n renderRange: [0, 0],\n containerSize: {\n width: windowWidth,\n height: windowHeight,\n },\n })\n Object.assign(this, {\n id,\n cacheCount,\n lowerThresholdCount,\n upperThresholdCount,\n skipContainerMeasure: !!skipContainerMeasure,\n })\n this.nodeCacheBackward = cacheCount\n this.nodeCacheForward = cacheCount\n this.setupSubscriptions()\n if (!skipContainerMeasure) {\n getRectSizeSync(`#${id}`, 100).then(({ width = windowWidth, height = windowHeight }) => {\n this.setStateIn('containerSize', {\n width,\n height,\n })\n })\n }\n this.renderInitialLayout()\n }\n\n /**\n * 设置订阅事件\n */\n private setupSubscriptions() {\n /** 滚动:先更新触底阈值,再判触顶/触底并更新分组与总高度,避免同一帧内沿用无效阈值。 */\n this.sub('scrollOffset', () => {\n const sectionSize = this.sections.length\n const lastSection = this.sections[sectionSize - 1]\n if (lastSection?.columnMap.every((column) => column[column.length - 1]?.getState().layouted)) {\n this.setLowerThresholdScrollTop()\n }\n this.setStateIn('renderRange', this.getSectionRenderRange())\n this.handleReachThreshold()\n this.updateScrollHeight()\n })\n\n this.sub(RootEvents.AllSectionsLayouted, () => {\n this.updateScrollHeight()\n this.setUpperThresholdScrollTop()\n this.setLowerThresholdScrollTop()\n })\n\n this.sub(RootEvents.Resize, () => {\n this.updateScrollHeight()\n this.setUpperThresholdScrollTop()\n this.setLowerThresholdScrollTop()\n })\n }\n\n /**\n * 渐进式渲染\n *\n * 因为初始没法知道每个分组的高度信息,不知道渲染边界,所以需要渐进式渲染\n *\n * 当目前的渲染批次的首个分组的scrollTop大于容器的高度,说明容器可视区域已经填满,没必要再往下渲染了\n *\n * @param [i=0] 从第几个分组开始渲染\n *\n */\n renderInitialLayout(i = 0) {\n nextTick(() => {\n const sectionSize = this.sections.length\n\n if (i >= sectionSize || i < 0) {\n this.pub(RootEvents.InitialRenderCompleted, null)\n return\n }\n const section = this.sections[i]\n section.layoutedSignal.promise.then(() => {\n this.setStateIn('renderRange', [0, i + 1 > sectionSize ? sectionSize - 1 : i + 1])\n // skipContainerMeasure(nestedScroll 模式):需布局全部 section,使 scrollHeight 展开供父容器滚动\n // default 模式:容器可视区域已填满则提前终止,减少首屏渲染\n if (\n !this.skipContainerMeasure &&\n section.getState().scrollTop > this.getState().containerSize.height\n ) {\n this.pub(RootEvents.InitialRenderCompleted, section)\n return\n }\n\n this.renderInitialLayout(i + 1)\n })\n })\n }\n\n /**\n * 计算滚动阈值对应的 scrollTop 并设置 upperThresholdScrollTop\n * 当距顶部还有 upperThresholdCount 个 FlowItem 时的 scrollTop 值\n */\n private setUpperThresholdScrollTop() {\n // 如果没有设置阈值或阈值为0,则返回0\n if (!this.upperThresholdCount) {\n this.upperThresholdScrollTop = 0\n return 0\n }\n const sectionSize = this.sections.length\n const tracker = Array.from(\n { length: sectionSize },\n () => new Map<number, { accCount: number, accHeight: number }>() // Map<列, { 当前列累计个数,当前列累计高度 }>\n )\n\n // 从第一个分组开始扫描\n loopSeciton: for (let i = 0; i < sectionSize; i++) {\n const section = this.sections[i]\n const sectionTracker = tracker[i]\n const columnMap = section.columnMap\n // 扫描当前分组的每一列\n for (let col = 0; col < columnMap.length; col++) {\n const column = columnMap[col]\n const columnSize = column.length\n if (!sectionTracker.has(col)) {\n if (i === 0) {\n sectionTracker.set(col, { accCount: 0, accHeight: 0 })\n } else {\n const previousSectionTracker = tracker[i - 1]\n sectionTracker.set(col, {\n accCount: Math.max(...[...previousSectionTracker.values()].map((nodeTracker) => nodeTracker.accCount)),\n accHeight: section.getState().scrollTop,\n })\n }\n }\n const colTracker = sectionTracker.get(col)!\n // 扫描当前列的每一行\n loopItem: for (let j = 0; j < columnSize; j++) {\n colTracker.accCount += 1\n colTracker.accHeight += column[j].getState().height + (j === 0 ? 0 : section.rowGap)\n if (colTracker.accCount >= this.upperThresholdCount) {\n break loopItem\n }\n }\n }\n for (const [, colTracker] of sectionTracker) {\n if (colTracker.accCount >= this.upperThresholdCount) {\n this.upperThresholdScrollTop = colTracker.accHeight\n break loopSeciton\n }\n }\n }\n return this.upperThresholdScrollTop\n }\n\n /**\n * 计算滚动阈值对应的 scrollTop 并设置 lowerThresholdScrollTop\n * 当距底部还有 lowerThresholdCount 个 FlowItem 时的 scrollTop 值\n */\n private setLowerThresholdScrollTop() {\n // 与 setUpperThresholdScrollTop 一致:0 或 undefined 时用「内容底 - 容器高」作为触底阈值\n if (!this.lowerThresholdCount) {\n // 必须用 sectionRange 实时计算,避免依赖可能未更新的 scrollHeight 状态\n const range = this.sectionRange\n const totalHeight = range.length > 0 ? range[range.length - 1][1] : 0\n // 触底判定:scrollOffset + containerSize.height >= lowerThresholdScrollTop\n // 须存内容底边 totalHeight(H)。若误存 H-h,则顶部时 h 与 H-h 比较,当 2h>=H 会恒判为在触底区,误触 onScrollToLower。\n this.lowerThresholdScrollTop = totalHeight\n return 0\n }\n const sectionSize = this.sections.length\n const tracker = Array.from(\n { length: sectionSize },\n () => new Map<number, { accCount: number, scrollTop: number }>()\n )\n // 从最后一个分组开始计算\n loopSeciton: for (let i = sectionSize - 1; i >= 0; i--) {\n const section = this.sections[i]\n const sectionTracker = tracker[i]\n const columnMap = section.columnMap\n // 扫描当前分组的每一列\n for (let col = 0; col < columnMap.length; col++) {\n const column = columnMap[col]\n const columnSize = column.length\n if (!sectionTracker.has(col)) {\n if (i === sectionSize - 1) {\n sectionTracker.set(col, { accCount: 0, scrollTop: 0 })\n } else {\n const belowSectionTracker = tracker[i + 1]\n sectionTracker.set(col, {\n accCount: Math.max(...[...belowSectionTracker.values()].map((nodeTracker) => nodeTracker.accCount)),\n scrollTop: 0,\n })\n }\n }\n const colTracker = sectionTracker.get(col)!\n // 从当前列的最后一行开始往前扫描\n loopItem: for (let j = columnSize - 1; j >= 0; j--) {\n colTracker.accCount += 1\n colTracker.scrollTop = column[j].getState().scrollTop\n if (colTracker.accCount >= this.lowerThresholdCount) {\n break loopItem\n }\n }\n }\n\n for (const [, colTracker] of sectionTracker) {\n if (colTracker.accCount >= this.lowerThresholdCount) {\n this.lowerThresholdScrollTop = colTracker.scrollTop\n break loopSeciton\n }\n }\n }\n\n return this.lowerThresholdScrollTop\n }\n\n /**\n * 处理滚动到阈值的情况\n * 检测当前滚动位置是否达到了上下阈值,并触发相应的事件\n * scrollElement 模式:scrollOffset 为内容内偏移(scrollTop - startOffset),upper/lowerThresholdScrollTop 基于本组件内容计算,触顶/触底以本 WaterFlow 内容为基准\n */\n private handleReachThreshold() {\n const { scrollOffset, containerSize } = this.getState()\n const inUpper = this.upperThresholdScrollTop !== -Infinity && scrollOffset <= this.upperThresholdScrollTop\n const inLower = this.lowerThresholdScrollTop !== Infinity && scrollOffset + containerSize.height >= this.lowerThresholdScrollTop\n if (inUpper && !this._inUpperZone) this.pub(RootEvents.ReachUpperThreshold)\n if (inLower && !this._inLowerZone) this.pub(RootEvents.ReachLowerThreshold)\n this._inUpperZone = inUpper\n this._inLowerZone = inLower\n }\n\n /**\n * 列表追加并完成 finalize 后调用:重置触底边沿状态(_inLowerZone),\n * 使用户仍在底部时下一次滚动能再次触发 onScrollToLower,而不必先上滑再下滑。\n * 不在此处同步调用 handleReachThreshold,避免仍在底部时立刻连发触底(与误触区分)。\n */\n public resetLowerReachEdgeAfterContentChange () {\n this._inLowerZone = false\n }\n\n /**\n * 容器的滚动上边界\n */\n get scrollBoundaryStart() {\n return this.getState().scrollOffset\n }\n\n /**\n * 容器的滚动下边界\n */\n get scrollBoundaryEnd() {\n return this.scrollBoundaryStart + this.getStateIn('containerSize').height\n }\n\n /**\n * 计算每个section的底部位置\n *\n * sectionBottomRange = [ [section1.top, section1.bottom], [section2.top, section2.bottom], ..., [sectionN.top, sectionN.bottom] ]\n *\n * @returns [number,number][]\n */\n get sectionRange() {\n const length = this.sections.length\n if (length === 0) return []\n const range = Array.from({ length }, () => [0, this.sections[0].maxColumnHeight])\n for (let i = 1; i < length; i++) {\n const previous = range[i - 1]\n const prevSection = this.sections[i - 1]\n const gap = prevSection.rowGap ?? 0\n range[i] = [previous[1] + gap, previous[1] + gap + this.sections[i].maxColumnHeight]\n }\n\n return range\n }\n\n /**\n * 更新总滚动高度(各 Section 累计)。\n * @param immediate true 时跳过 raf 防抖(如 finalizePushNodesStateIfNeeded),避免高度滞后引起跳动\n */\n public updateScrollHeight(immediate = false) {\n const flush = () => {\n const next = this.sectionRange[this.sectionRange.length - 1]?.[1] ?? 0\n this.setStateIn('scrollHeight', next)\n }\n if (immediate) {\n if (this._scrollHeightRafId != null) {\n cancelAnimationFrame(this._scrollHeightRafId)\n this._scrollHeightRafId = null\n }\n flush()\n return\n }\n if (this._scrollHeightRafId != null) {\n cancelAnimationFrame(this._scrollHeightRafId)\n }\n this._scrollHeightRafId = requestAnimationFrame(() => {\n this._scrollHeightRafId = null\n flush()\n })\n }\n\n /**\n * 注册分组\n */\n public registerSection(section: Section) {\n const { id, order } = section\n this.sectionMap.set(id, section)\n this.sections[order] = section\n }\n\n /**\n * 注册节点\n */\n public registerNode(node: Node) {\n this.nodeMap.set(node.id, node)\n }\n\n /**\n * 查找分组\n */\n public findSection(id: string) {\n return this.sectionMap.get(id)\n }\n\n /**\n * 查找节点\n */\n public findNode(id: string) {\n return this.nodeMap.get(id)\n }\n\n /**\n * 设置 Node 层上下方向预缓存条数,并刷新可见分组内的列渲染区间。\n */\n public setNodeCacheRange (backward: number, forward: number) {\n const b = Math.max(0, Math.floor(backward))\n const f = Math.max(0, Math.floor(forward))\n if (this.nodeCacheBackward === b && this.nodeCacheForward === f) {\n return\n }\n this.nodeCacheBackward = b\n this.nodeCacheForward = f\n for (const section of this.sections) {\n if (section.isInRange) {\n section.setStateIn('renderRange', section.getNodeRenderRange())\n }\n }\n }\n\n /**\n * 获取分组渲染区间\n */\n public getSectionRenderRange() {\n const result: [number, number] = [Infinity, -Infinity]\n\n for (let i = 0; i < this.sections.length; i++) {\n const section = this.sections[i]\n if (section.isInRange) {\n result[0] = Math.min(result[0], i)\n result[1] = Math.max(result[1], i)\n }\n }\n\n if (result[0] === Infinity) {\n result[0] = 0\n }\n\n if (result[1] === -Infinity) {\n result[1] = this.sections.length - 1\n }\n\n const [backwardCache, forwardCache] = this.calcCacheSection(result)\n // 双向预缓存,避免反向滚动时出现空白(原逻辑仅在滚动方向缓存,反向时未预渲染)\n const backwardDistance = backwardCache\n const forwardDistance = forwardCache\n\n const overscanBackward = result[0] - backwardDistance\n const overscanForward = result[1] + forwardDistance\n\n result[0] = overscanBackward < 0 ? 0 : overscanBackward\n\n result[1] = overscanForward > this.sections.length ? this.sections.length - 1 : overscanForward\n\n const prevRange = this.getState().renderRange\n return isSameRenderRange(result, prevRange) ? prevRange : result\n }\n\n /**\n * 计算预渲染的分组个数\n */\n private calcCacheSection(renderRange: [number, number]) {\n const clientHeight = this.getState().containerSize.height\n const sectionCount = this.sectionMap.size\n let [start, end] = renderRange\n let cacheBackward = 1\n let cacheForward = 1\n\n if (start > 0) {\n let acc = this.sections[--start]?.getState().height ?? 0\n while (--start > 0) {\n const prevSection = this.sections[start]\n acc += prevSection.getState().height\n cacheBackward += 1\n if (acc >= clientHeight >>> 1) {\n break\n }\n }\n }\n\n if (end < sectionCount - 1) {\n let acc = this.sections[++end]?.getState().height ?? 0\n while (++end < sectionCount - 1) {\n const nextSection = this.sections[end]\n acc += nextSection.getState().height\n cacheForward += 1\n if (acc >= clientHeight >>> 1) {\n break\n }\n }\n }\n\n return [cacheBackward, cacheForward]\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -57,6 +57,8 @@ export declare class Section extends StatefulEventBus<SectionState> {
|
|
|
57
57
|
resolve: () => void;
|
|
58
58
|
reject: (reason?: any) => void;
|
|
59
59
|
};
|
|
60
|
+
/** pushNodesStructuralOnly 后待 finalize;由 WaterFlow 的 useLayoutEffect 收尾,避免在父 render 中更新子 state */
|
|
61
|
+
private _pendingPushFinalize;
|
|
60
62
|
constructor(root: Root, props: SectionProps);
|
|
61
63
|
/**
|
|
62
64
|
* 订阅事件
|
|
@@ -107,6 +109,10 @@ export declare class Section extends StatefulEventBus<SectionState> {
|
|
|
107
109
|
*/
|
|
108
110
|
getNodeRenderRange(): [number, number][];
|
|
109
111
|
pushNode(nodeIndex: number, col: number): void;
|
|
112
|
+
/** 仅扩展 columnMap / 注册 Node,不 setState;与 finalizePushNodesStateIfNeeded 配对 */
|
|
113
|
+
pushNodesStructuralOnly(count: number): void;
|
|
114
|
+
/** 在 commit 后同步 height、节点位置与 scrollHeight(见 WaterFlow useLayoutEffect) */
|
|
115
|
+
finalizePushNodesStateIfNeeded(): void;
|
|
110
116
|
pushNodes(count: number): void;
|
|
111
117
|
}
|
|
112
118
|
export {};
|
|
@@ -25,6 +25,8 @@ class Section extends StatefulEventBus {
|
|
|
25
25
|
this.rowGap = 0;
|
|
26
26
|
this.columnGap = 0;
|
|
27
27
|
this.layoutedSignal = createImperativePromise();
|
|
28
|
+
/** pushNodesStructuralOnly 后待 finalize;由 WaterFlow 的 useLayoutEffect 收尾,避免在父 render 中更新子 state */
|
|
29
|
+
this._pendingPushFinalize = false;
|
|
28
30
|
Object.assign(this, {
|
|
29
31
|
id,
|
|
30
32
|
col,
|
|
@@ -198,14 +200,26 @@ class Section extends StatefulEventBus {
|
|
|
198
200
|
if (end === -Infinity) {
|
|
199
201
|
result[i][1] = -1;
|
|
200
202
|
}
|
|
201
|
-
const
|
|
202
|
-
const
|
|
203
|
-
const backwardDistance = scrollDirection === 'backward' ? cacheCount : 0;
|
|
204
|
-
const forwardDistance = scrollDirection === 'forward' ? cacheCount : 0;
|
|
203
|
+
const backwardDistance = this.root.nodeCacheBackward;
|
|
204
|
+
const forwardDistance = this.root.nodeCacheForward;
|
|
205
205
|
const overscanBackward = result[i][0] - backwardDistance;
|
|
206
206
|
const overscanForward = result[i][1] + forwardDistance;
|
|
207
207
|
result[i][0] = overscanBackward < 0 ? 0 : overscanBackward;
|
|
208
208
|
result[i][1] = overscanForward > column.length ? column.length - 1 : overscanForward;
|
|
209
|
+
// 列尾连续未测量节点纳入渲染区间,保证追加数据后能挂载并完成 measure
|
|
210
|
+
let tailUnmeasuredStart = column.length;
|
|
211
|
+
for (let j = column.length - 1; j >= 0; j--) {
|
|
212
|
+
if (!column[j].getState().layouted) {
|
|
213
|
+
tailUnmeasuredStart = j;
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (tailUnmeasuredStart < column.length) {
|
|
220
|
+
result[i][0] = Math.min(result[i][0], tailUnmeasuredStart);
|
|
221
|
+
result[i][1] = Math.max(result[i][1], column.length - 1);
|
|
222
|
+
}
|
|
209
223
|
}
|
|
210
224
|
const prevRange = this.getState().renderRange;
|
|
211
225
|
return isSameRenderRange(result, prevRange) ? prevRange : result;
|
|
@@ -221,19 +235,42 @@ class Section extends StatefulEventBus {
|
|
|
221
235
|
this.register(node);
|
|
222
236
|
this.root.registerNode(node);
|
|
223
237
|
}
|
|
224
|
-
|
|
238
|
+
/** 仅扩展 columnMap / 注册 Node,不 setState;与 finalizePushNodesStateIfNeeded 配对 */
|
|
239
|
+
pushNodesStructuralOnly(count) {
|
|
225
240
|
const { count: originalCount, col } = this;
|
|
226
241
|
for (let i = originalCount; i < originalCount + count; i++) {
|
|
227
242
|
this.pushNode(i, col);
|
|
228
243
|
}
|
|
229
244
|
this.count += count;
|
|
230
245
|
this.root.lowerThresholdScrollTop = Infinity;
|
|
246
|
+
this._pendingPushFinalize = true;
|
|
247
|
+
}
|
|
248
|
+
/** 在 commit 后同步 height、节点位置与 scrollHeight(见 WaterFlow useLayoutEffect) */
|
|
249
|
+
finalizePushNodesStateIfNeeded() {
|
|
250
|
+
if (!this._pendingPushFinalize)
|
|
251
|
+
return;
|
|
252
|
+
this._pendingPushFinalize = false;
|
|
231
253
|
// 同步 section state.height,避免与 maxColumnHeight 不一致导致 footer 错位
|
|
232
254
|
this.setStateIn('height', this.maxColumnHeight);
|
|
233
255
|
this.updateNodes();
|
|
234
256
|
this.updateBehindSectionsPosition();
|
|
235
257
|
// 立即更新 scrollHeight,避免防抖导致容器高度滞后引发往上抖动
|
|
236
258
|
this.root.updateScrollHeight(true);
|
|
259
|
+
if (this.isInRange) {
|
|
260
|
+
this.setStateIn('renderRange', this.getNodeRenderRange());
|
|
261
|
+
}
|
|
262
|
+
// 扩展 Root 的 section 切片,保证多 FlowSection 时当前分组始终在渲染树内
|
|
263
|
+
const [rStart, rEnd] = this.root.getState().renderRange;
|
|
264
|
+
const newStart = Math.min(rStart, this.order);
|
|
265
|
+
const newEnd = Math.max(rEnd, this.order);
|
|
266
|
+
if (newStart !== rStart || newEnd !== rEnd) {
|
|
267
|
+
this.root.setStateIn('renderRange', [newStart, newEnd]);
|
|
268
|
+
}
|
|
269
|
+
this.root.resetLowerReachEdgeAfterContentChange();
|
|
270
|
+
}
|
|
271
|
+
pushNodes(count) {
|
|
272
|
+
this.pushNodesStructuralOnly(count);
|
|
273
|
+
this.finalizePushNodesStateIfNeeded();
|
|
237
274
|
}
|
|
238
275
|
}
|
|
239
276
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section.js","sources":["../../../src/components/water-flow/section.ts"],"sourcesContent":["import { debounce } from '../../utils'\nimport { Size } from './interface'\nimport { Node } from './node'\nimport { Root, RootEvents } from './root'\nimport { StatefulEventBus } from './stateful-event-bus'\nimport { createImperativePromise, getMatrixPosition, isSameRenderRange } from './utils'\n\nexport interface SectionProps {\n /** 分组的唯一标识 */\n id: string\n /** 分组的列数 */\n col: number\n /** 分组的顺序 */\n order: number\n /** 节点数量 */\n count: number\n /** 该分组的行间距 */\n rowGap: number\n /** 该分组的列间距 */\n columnGap: number\n}\n\n/**\n * 分组状态\n */\ntype SectionState = {\n /**\n * 分组是否已经布局计算\n */\n layouted: boolean\n /**\n * 分组顶部距离容器顶部的距离\n */\n scrollTop: number\n /**\n * 分组的高度\n */\n height: number\n /**\n * 每个列的渲染范围\n * 每个元素为一个二元组,第一个元素为起始索引,第二个元素为结束索引\n */\n renderRange: [number, number][]\n}\n\nexport const SectionEvents = {\n AllNodesLayouted: Symbol.for('AllNodesLayouted'),\n Resize: Symbol.for('Resize'),\n}\n\nexport class Section extends StatefulEventBus<SectionState> {\n id: string\n order: number\n col: number\n columnMap: Node[][]\n nodes: Map<string, Node> = new Map()\n defaultSize = 200\n count = 0\n rowGap = 0\n columnGap = 0\n layoutedSignal = createImperativePromise()\n\n constructor(public root: Root, props: SectionProps) {\n const { id, col, order, count, rowGap, columnGap } = props\n super({\n layouted: false,\n scrollTop: 0,\n height: 0,\n renderRange: Array.from({ length: col }, () => [0, 0]),\n })\n Object.assign(this, {\n id,\n col,\n count,\n order,\n rowGap,\n columnGap,\n columnMap: Array.from({ length: col }, () => []),\n })\n this.initializeColumnMap()\n root.registerSection(this)\n this.setupSubscriptions()\n }\n\n /**\n * 订阅事件\n */\n private setupSubscriptions() {\n // 分组的所有节点完成初次布局计算,Nodes的实际高度已经拿到,那么这时分组的高度是确定的,距离滚动容器的顶部距离也是确定的,可以开始计算\n this.sub(SectionEvents.AllNodesLayouted, () => {\n this.setStateBatch({\n scrollTop: this.calcScrollTop(),\n height: this.maxColumnHeight,\n })\n this.updateNodes()\n this.setStateIn('renderRange', this.getNodeRenderRange())\n this.setStateIn('layouted', true)\n this.layoutedSignal.resolve()\n if (this.root.sections.every((section) => section.getState().layouted)) {\n this.root.pub(RootEvents.AllSectionsLayouted)\n }\n })\n // 滚动过程中,如果分组自身可见,那么需要计算分组内应该渲染的元素节点索引区间\n this.root.sub('scrollOffset', () => {\n if (this.isInRange) {\n this.setStateIn('renderRange', this.getNodeRenderRange())\n }\n })\n\n /**\n * 对应分组内的节点尺寸发生变化,需要重新进行相关计算\n * 1. 重新计算尺寸发生变化的节点所在列的所有节点位置信息\n * 2. 重新计算分组的高度\n * 3. 重新计算当前分组之后的所有分组的scrollTop以及分组内的节点位置\n * 4. 更新分组内节点的渲染范围\n */\n this.sub<{ node: Node, newSize: Size, originalSize: Size }>(\n SectionEvents.Resize,\n debounce(() => {\n this.setStateIn('height', this.maxColumnHeight)\n this.updateBehindSectionsPosition()\n if (this.isInRange) {\n this.setStateIn('renderRange', this.getNodeRenderRange())\n }\n this.root.pub(RootEvents.Resize)\n })\n )\n }\n\n /**\n * 获取当前分组的最大高度,分组的最大高度由分组最高列决定\n * @returns 当前分组的最大高度\n */\n get maxColumnHeight() {\n return Math.max(\n ...this.columnMap.map(\n (column) => column.reduce((buf, node) => buf + node.getState().height, 0) + (column.length - 1) * this.rowGap\n )\n )\n }\n\n /**\n * 当前分组是否在可视区域\n *\n * 滚动偏移为 scrollOffset,容器的高度为 containerSize.height\n *\n * 当前容器滚动上边界(scrollBoundaryStart)为 scrollOffset,容器滚动的下边界(scrollBoundaryEnd)为 scrollOffset + containerSize.height\n *\n * 如果分组的 scrollTop 小于滚动下边界并且 scrollTop + 分组高度大于滚动上边界,那么分组在可视区域\n */\n get isInRange() {\n const { scrollBoundaryStart, scrollBoundaryEnd } = this.root\n const { height: sectionHeight, scrollTop: sectionScrollTop } = this.getState()\n return sectionScrollTop <= scrollBoundaryEnd && sectionScrollTop + sectionHeight >= scrollBoundaryStart\n }\n\n /**\n * 注册节点\n */\n private register(node: Node) {\n const { col, order } = node\n this.columnMap[col][order] = node\n this.nodes.set(node.id, node)\n }\n\n /**\n * 初始化分组内的列,即将一维数组转二维数组\n */\n private initializeColumnMap() {\n const { count, col } = this\n for (let i = 0; i < count; i++) {\n this.pushNode(i, col)\n }\n }\n\n /**\n * 更新当前分组之后的分组的位置信息\n */\n private updateBehindSectionsPosition() {\n let start = this.order + 1\n if (start > this.root.sections.length) {\n return\n }\n for (; start < this.root.sections.length; start++) {\n const currentSection = this.root.sections[start - 1]\n const nextSection = this.root.sections[start]\n // 使用 maxColumnHeight 替代 getState().height,避免 pushNodes 后 state 未同步导致 footer 错位\n const effectiveHeight = currentSection.maxColumnHeight\n const newScrollTop = currentSection.getState().scrollTop + effectiveHeight + this.rowGap\n nextSection.setStateIn('scrollTop', newScrollTop)\n nextSection.updateNodes()\n }\n }\n\n /**\n * 更新指定列的节点位置信息\n * @param col 列索引\n */\n private updateColumnNode(col: number) {\n const column = this.columnMap[col]\n const { scrollTop: sectionScrollTop } = this.getState()\n for (let i = 0; i < column.length; i++) {\n const node = column[i]\n if (i === 0) {\n node.setStateBatch({\n scrollTop: sectionScrollTop,\n top: 0,\n })\n } else {\n const prevNode = column[i - 1]\n const { scrollTop: prevNodeScrollTop, height: prevNodeHeight, top: prevNodeTop } = prevNode.getState()\n node.setStateBatch({\n scrollTop: prevNodeScrollTop + prevNodeHeight + this.rowGap,\n top: prevNodeHeight + prevNodeTop + this.rowGap,\n })\n }\n }\n }\n\n /**\n * 更新每列节点的位置\n */\n private updateNodes() {\n for (let col = 0; col < this.columnMap.length; col++) {\n this.updateColumnNode(col)\n }\n }\n\n /**\n * 计算当前分组的 scrollTop,即该分组之前的所有分组的最大列高度 + rowGap 之和\n */\n private calcScrollTop() {\n return this.root.sections.slice(0, this.order).reduce(\n (acc, section) => acc + section.maxColumnHeight + (section.rowGap ?? 0),\n 0\n )\n }\n\n /**\n * 计算当前分组内每列应该渲染的节点索引区间\n */\n public getNodeRenderRange() {\n if (!this.isInRange) {\n return Array.from({ length: this.col }, () => [0, -1] as [number, number])\n }\n\n const result = Array.from({ length: this.col }, () => [Infinity, -Infinity] as unknown as [number, number])\n for (let i = 0; i < this.columnMap.length; i++) {\n const column = this.columnMap[i]\n for (let j = 0; j < column.length; j++) {\n const node = column[j]\n if (node.isInRange) {\n result[i][0] = Math.min(result[i][0], j)\n result[i][1] = Math.max(result[i][1], j)\n }\n }\n const start = result[i][0]\n const end = result[i][1]\n if (start === Infinity) {\n result[i][0] = 0\n }\n if (end === -Infinity) {\n result[i][1] = -1\n }\n\n const cacheCount = this.root.cacheCount\n const scrollDirection = this.root.getState().scrollDirection\n const backwardDistance = scrollDirection === 'backward' ? cacheCount : 0\n const forwardDistance = scrollDirection === 'forward' ? cacheCount : 0\n const overscanBackward = result[i][0] - backwardDistance\n const overscanForward = result[i][1] + forwardDistance\n result[i][0] = overscanBackward < 0 ? 0 : overscanBackward\n result[i][1] = overscanForward > column.length ? column.length - 1 : overscanForward\n }\n\n const prevRange = this.getState().renderRange\n return isSameRenderRange(result, prevRange) ? prevRange : result\n }\n\n public pushNode(nodeIndex: number, col: number) {\n const { row: rowIndex, col: columnIndex } = getMatrixPosition(nodeIndex, col)\n const node = new Node(this.root, this, {\n childIndex: nodeIndex,\n order: rowIndex,\n col: columnIndex,\n height: this.defaultSize,\n })\n this.register(node)\n this.root.registerNode(node)\n }\n\n public pushNodes(count: number) {\n const { count: originalCount, col } = this\n for (let i = originalCount; i < originalCount + count; i++) {\n this.pushNode(i, col)\n }\n this.count += count\n this.root.lowerThresholdScrollTop = Infinity\n // 同步 section state.height,避免与 maxColumnHeight 不一致导致 footer 错位\n this.setStateIn('height', this.maxColumnHeight)\n this.updateNodes()\n this.updateBehindSectionsPosition()\n // 立即更新 scrollHeight,避免防抖导致容器高度滞后引发往上抖动\n this.root.updateScrollHeight(true)\n }\n}\n"],"names":[],"mappings":";;;;;;;AA6Ca,MAAA,aAAa,GAAG;AAC3B,IAAA,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC;AAChD,IAAA,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;;AAGxB,MAAO,OAAQ,SAAQ,gBAA8B,CAAA;IAYzD,WAAmB,CAAA,IAAU,EAAE,KAAmB,EAAA;AAChD,QAAA,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK;AAC1D,QAAA,KAAK,CAAC;AACJ,YAAA,QAAQ,EAAE,KAAK;AACf,YAAA,SAAS,EAAE,CAAC;AACZ,YAAA,MAAM,EAAE,CAAC;AACT,YAAA,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACvD,SAAA,CAAC;QAPe,IAAI,CAAA,IAAA,GAAJ,IAAI;AAPvB,QAAA,IAAA,CAAA,KAAK,GAAsB,IAAI,GAAG,EAAE;QACpC,IAAW,CAAA,WAAA,GAAG,GAAG;QACjB,IAAK,CAAA,KAAA,GAAG,CAAC;QACT,IAAM,CAAA,MAAA,GAAG,CAAC;QACV,IAAS,CAAA,SAAA,GAAG,CAAC;QACb,IAAc,CAAA,cAAA,GAAG,uBAAuB,EAAE;AAUxC,QAAA,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;YAClB,EAAE;YACF,GAAG;YACH,KAAK;YACL,KAAK;YACL,MAAM;YACN,SAAS;AACT,YAAA,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC;AACjD,SAAA,CAAC;QACF,IAAI,CAAC,mBAAmB,EAAE;AAC1B,QAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;QAC1B,IAAI,CAAC,kBAAkB,EAAE;;AAG3B;;AAEG;IACK,kBAAkB,GAAA;;QAExB,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,gBAAgB,EAAE,MAAK;YAC5C,IAAI,CAAC,aAAa,CAAC;AACjB,gBAAA,SAAS,EAAE,IAAI,CAAC,aAAa,EAAE;gBAC/B,MAAM,EAAE,IAAI,CAAC,eAAe;AAC7B,aAAA,CAAC;YACF,IAAI,CAAC,WAAW,EAAE;YAClB,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC;AACzD,YAAA,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,IAAI,CAAC;AACjC,YAAA,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;YAC7B,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE;gBACtE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,mBAAmB,CAAC;;AAEjD,SAAC,CAAC;;QAEF,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,MAAK;AACjC,YAAA,IAAI,IAAI,CAAC,SAAS,EAAE;gBAClB,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC;;AAE7D,SAAC,CAAC;AAEF;;;;;;AAMG;QACH,IAAI,CAAC,GAAG,CACN,aAAa,CAAC,MAAM,EACpB,QAAQ,CAAC,MAAK;YACZ,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC;YAC/C,IAAI,CAAC,4BAA4B,EAAE;AACnC,YAAA,IAAI,IAAI,CAAC,SAAS,EAAE;gBAClB,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC;;YAE3D,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;SACjC,CAAC,CACH;;AAGH;;;AAGG;AACH,IAAA,IAAI,eAAe,GAAA;QACjB,OAAO,IAAI,CAAC,GAAG,CACb,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CACnB,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,CAC9G,CACF;;AAGH;;;;;;;;AAQG;AACH,IAAA,IAAI,SAAS,GAAA;QACX,MAAM,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,IAAI;AAC5D,QAAA,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE;QAC9E,OAAO,gBAAgB,IAAI,iBAAiB,IAAI,gBAAgB,GAAG,aAAa,IAAI,mBAAmB;;AAGzG;;AAEG;AACK,IAAA,QAAQ,CAAC,IAAU,EAAA;AACzB,QAAA,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI;QAC3B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI;QACjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC;;AAG/B;;AAEG;IACK,mBAAmB,GAAA;AACzB,QAAA,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI;AAC3B,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;AAC9B,YAAA,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;;;AAIzB;;AAEG;IACK,4BAA4B,GAAA;AAClC,QAAA,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;QAC1B,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YACrC;;AAEF,QAAA,OAAO,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;AACjD,YAAA,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC;YACpD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;;AAE7C,YAAA,MAAM,eAAe,GAAG,cAAc,CAAC,eAAe;AACtD,YAAA,MAAM,YAAY,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAC,SAAS,GAAG,eAAe,GAAG,IAAI,CAAC,MAAM;AACxF,YAAA,WAAW,CAAC,UAAU,CAAC,WAAW,EAAE,YAAY,CAAC;YACjD,WAAW,CAAC,WAAW,EAAE;;;AAI7B;;;AAGG;AACK,IAAA,gBAAgB,CAAC,GAAW,EAAA;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;QAClC,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE;AACvD,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,YAAA,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC;AACtB,YAAA,IAAI,CAAC,KAAK,CAAC,EAAE;gBACX,IAAI,CAAC,aAAa,CAAC;AACjB,oBAAA,SAAS,EAAE,gBAAgB;AAC3B,oBAAA,GAAG,EAAE,CAAC;AACP,iBAAA,CAAC;;iBACG;gBACL,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;AAC9B,gBAAA,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,QAAQ,CAAC,QAAQ,EAAE;gBACtG,IAAI,CAAC,aAAa,CAAC;AACjB,oBAAA,SAAS,EAAE,iBAAiB,GAAG,cAAc,GAAG,IAAI,CAAC,MAAM;AAC3D,oBAAA,GAAG,EAAE,cAAc,GAAG,WAAW,GAAG,IAAI,CAAC,MAAM;AAChD,iBAAA,CAAC;;;;AAKR;;AAEG;IACK,WAAW,GAAA;AACjB,QAAA,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;AACpD,YAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;;;AAI9B;;AAEG;IACK,aAAa,GAAA;QACnB,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CACnD,CAAC,GAAG,EAAE,OAAO,KAAK,EAAA,IAAA,EAAA,CAAA,CAAA,OAAA,GAAG,GAAG,OAAO,CAAC,eAAe,IAAI,CAAA,EAAA,GAAA,OAAO,CAAC,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,CAAC,CAAC,CAAA,EAAA,EACvE,CAAC,CACF;;AAGH;;AAEG;IACI,kBAAkB,GAAA;AACvB,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAqB,CAAC;;QAG5E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAgC,CAAC;AAC3G,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;AAChC,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,gBAAA,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC;AACtB,gBAAA,IAAI,IAAI,CAAC,SAAS,EAAE;oBAClB,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBACxC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;;;YAG5C,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACxB,YAAA,IAAI,KAAK,KAAK,QAAQ,EAAE;gBACtB,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;;AAElB,YAAA,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE;gBACrB,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;;AAGnB,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU;YACvC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,eAAe;AAC5D,YAAA,MAAM,gBAAgB,GAAG,eAAe,KAAK,UAAU,GAAG,UAAU,GAAG,CAAC;AACxE,YAAA,MAAM,eAAe,GAAG,eAAe,KAAK,SAAS,GAAG,UAAU,GAAG,CAAC;YACtE,MAAM,gBAAgB,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,gBAAgB;YACxD,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe;AACtD,YAAA,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,gBAAgB,GAAG,CAAC,GAAG,CAAC,GAAG,gBAAgB;YAC1D,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,eAAe;;QAGtF,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,WAAW;AAC7C,QAAA,OAAO,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,SAAS,GAAG,MAAM;;IAG3D,QAAQ,CAAC,SAAiB,EAAE,GAAW,EAAA;AAC5C,QAAA,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,iBAAiB,CAAC,SAAS,EAAE,GAAG,CAAC;QAC7E,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE;AACrC,YAAA,UAAU,EAAE,SAAS;AACrB,YAAA,KAAK,EAAE,QAAQ;AACf,YAAA,GAAG,EAAE,WAAW;YAChB,MAAM,EAAE,IAAI,CAAC,WAAW;AACzB,SAAA,CAAC;AACF,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;AACnB,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;;AAGvB,IAAA,SAAS,CAAC,KAAa,EAAA;QAC5B,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,IAAI;AAC1C,QAAA,KAAK,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC,GAAG,aAAa,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;AAC1D,YAAA,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;;AAEvB,QAAA,IAAI,CAAC,KAAK,IAAI,KAAK;AACnB,QAAA,IAAI,CAAC,IAAI,CAAC,uBAAuB,GAAG,QAAQ;;QAE5C,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC;QAC/C,IAAI,CAAC,WAAW,EAAE;QAClB,IAAI,CAAC,4BAA4B,EAAE;;AAEnC,QAAA,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC;;AAErC;;;;"}
|
|
1
|
+
{"version":3,"file":"section.js","sources":["../../../src/components/water-flow/section.ts"],"sourcesContent":["import { debounce } from '../../utils'\nimport { Size } from './interface'\nimport { Node } from './node'\nimport { Root, RootEvents } from './root'\nimport { StatefulEventBus } from './stateful-event-bus'\nimport { createImperativePromise, getMatrixPosition, isSameRenderRange } from './utils'\n\nexport interface SectionProps {\n /** 分组的唯一标识 */\n id: string\n /** 分组的列数 */\n col: number\n /** 分组的顺序 */\n order: number\n /** 节点数量 */\n count: number\n /** 该分组的行间距 */\n rowGap: number\n /** 该分组的列间距 */\n columnGap: number\n}\n\n/**\n * 分组状态\n */\ntype SectionState = {\n /**\n * 分组是否已经布局计算\n */\n layouted: boolean\n /**\n * 分组顶部距离容器顶部的距离\n */\n scrollTop: number\n /**\n * 分组的高度\n */\n height: number\n /**\n * 每个列的渲染范围\n * 每个元素为一个二元组,第一个元素为起始索引,第二个元素为结束索引\n */\n renderRange: [number, number][]\n}\n\nexport const SectionEvents = {\n AllNodesLayouted: Symbol.for('AllNodesLayouted'),\n Resize: Symbol.for('Resize'),\n}\n\nexport class Section extends StatefulEventBus<SectionState> {\n id: string\n order: number\n col: number\n columnMap: Node[][]\n nodes: Map<string, Node> = new Map()\n defaultSize = 200\n count = 0\n rowGap = 0\n columnGap = 0\n layoutedSignal = createImperativePromise()\n\n /** pushNodesStructuralOnly 后待 finalize;由 WaterFlow 的 useLayoutEffect 收尾,避免在父 render 中更新子 state */\n private _pendingPushFinalize = false\n\n constructor(public root: Root, props: SectionProps) {\n const { id, col, order, count, rowGap, columnGap } = props\n super({\n layouted: false,\n scrollTop: 0,\n height: 0,\n renderRange: Array.from({ length: col }, () => [0, 0]),\n })\n Object.assign(this, {\n id,\n col,\n count,\n order,\n rowGap,\n columnGap,\n columnMap: Array.from({ length: col }, () => []),\n })\n this.initializeColumnMap()\n root.registerSection(this)\n this.setupSubscriptions()\n }\n\n /**\n * 订阅事件\n */\n private setupSubscriptions() {\n // 分组的所有节点完成初次布局计算,Nodes的实际高度已经拿到,那么这时分组的高度是确定的,距离滚动容器的顶部距离也是确定的,可以开始计算\n this.sub(SectionEvents.AllNodesLayouted, () => {\n this.setStateBatch({\n scrollTop: this.calcScrollTop(),\n height: this.maxColumnHeight,\n })\n this.updateNodes()\n this.setStateIn('renderRange', this.getNodeRenderRange())\n this.setStateIn('layouted', true)\n this.layoutedSignal.resolve()\n if (this.root.sections.every((section) => section.getState().layouted)) {\n this.root.pub(RootEvents.AllSectionsLayouted)\n }\n })\n // 滚动过程中,如果分组自身可见,那么需要计算分组内应该渲染的元素节点索引区间\n this.root.sub('scrollOffset', () => {\n if (this.isInRange) {\n this.setStateIn('renderRange', this.getNodeRenderRange())\n }\n })\n\n /**\n * 对应分组内的节点尺寸发生变化,需要重新进行相关计算\n * 1. 重新计算尺寸发生变化的节点所在列的所有节点位置信息\n * 2. 重新计算分组的高度\n * 3. 重新计算当前分组之后的所有分组的scrollTop以及分组内的节点位置\n * 4. 更新分组内节点的渲染范围\n */\n this.sub<{ node: Node, newSize: Size, originalSize: Size }>(\n SectionEvents.Resize,\n debounce(() => {\n this.setStateIn('height', this.maxColumnHeight)\n this.updateBehindSectionsPosition()\n if (this.isInRange) {\n this.setStateIn('renderRange', this.getNodeRenderRange())\n }\n this.root.pub(RootEvents.Resize)\n })\n )\n }\n\n /**\n * 获取当前分组的最大高度,分组的最大高度由分组最高列决定\n * @returns 当前分组的最大高度\n */\n get maxColumnHeight() {\n return Math.max(\n ...this.columnMap.map(\n (column) => column.reduce((buf, node) => buf + node.getState().height, 0) + (column.length - 1) * this.rowGap\n )\n )\n }\n\n /**\n * 当前分组是否在可视区域\n *\n * 滚动偏移为 scrollOffset,容器的高度为 containerSize.height\n *\n * 当前容器滚动上边界(scrollBoundaryStart)为 scrollOffset,容器滚动的下边界(scrollBoundaryEnd)为 scrollOffset + containerSize.height\n *\n * 如果分组的 scrollTop 小于滚动下边界并且 scrollTop + 分组高度大于滚动上边界,那么分组在可视区域\n */\n get isInRange() {\n const { scrollBoundaryStart, scrollBoundaryEnd } = this.root\n const { height: sectionHeight, scrollTop: sectionScrollTop } = this.getState()\n return sectionScrollTop <= scrollBoundaryEnd && sectionScrollTop + sectionHeight >= scrollBoundaryStart\n }\n\n /**\n * 注册节点\n */\n private register(node: Node) {\n const { col, order } = node\n this.columnMap[col][order] = node\n this.nodes.set(node.id, node)\n }\n\n /**\n * 初始化分组内的列,即将一维数组转二维数组\n */\n private initializeColumnMap() {\n const { count, col } = this\n for (let i = 0; i < count; i++) {\n this.pushNode(i, col)\n }\n }\n\n /**\n * 更新当前分组之后的分组的位置信息\n */\n private updateBehindSectionsPosition() {\n let start = this.order + 1\n if (start > this.root.sections.length) {\n return\n }\n for (; start < this.root.sections.length; start++) {\n const currentSection = this.root.sections[start - 1]\n const nextSection = this.root.sections[start]\n // 使用 maxColumnHeight 替代 getState().height,避免 pushNodes 后 state 未同步导致 footer 错位\n const effectiveHeight = currentSection.maxColumnHeight\n const newScrollTop = currentSection.getState().scrollTop + effectiveHeight + this.rowGap\n nextSection.setStateIn('scrollTop', newScrollTop)\n nextSection.updateNodes()\n }\n }\n\n /**\n * 更新指定列的节点位置信息\n * @param col 列索引\n */\n private updateColumnNode(col: number) {\n const column = this.columnMap[col]\n const { scrollTop: sectionScrollTop } = this.getState()\n for (let i = 0; i < column.length; i++) {\n const node = column[i]\n if (i === 0) {\n node.setStateBatch({\n scrollTop: sectionScrollTop,\n top: 0,\n })\n } else {\n const prevNode = column[i - 1]\n const { scrollTop: prevNodeScrollTop, height: prevNodeHeight, top: prevNodeTop } = prevNode.getState()\n node.setStateBatch({\n scrollTop: prevNodeScrollTop + prevNodeHeight + this.rowGap,\n top: prevNodeHeight + prevNodeTop + this.rowGap,\n })\n }\n }\n }\n\n /**\n * 更新每列节点的位置\n */\n private updateNodes() {\n for (let col = 0; col < this.columnMap.length; col++) {\n this.updateColumnNode(col)\n }\n }\n\n /**\n * 计算当前分组的 scrollTop,即该分组之前的所有分组的最大列高度 + rowGap 之和\n */\n private calcScrollTop() {\n return this.root.sections.slice(0, this.order).reduce(\n (acc, section) => acc + section.maxColumnHeight + (section.rowGap ?? 0),\n 0\n )\n }\n\n /**\n * 计算当前分组内每列应该渲染的节点索引区间\n */\n public getNodeRenderRange() {\n if (!this.isInRange) {\n return Array.from({ length: this.col }, () => [0, -1] as [number, number])\n }\n\n const result = Array.from({ length: this.col }, () => [Infinity, -Infinity] as unknown as [number, number])\n for (let i = 0; i < this.columnMap.length; i++) {\n const column = this.columnMap[i]\n for (let j = 0; j < column.length; j++) {\n const node = column[j]\n if (node.isInRange) {\n result[i][0] = Math.min(result[i][0], j)\n result[i][1] = Math.max(result[i][1], j)\n }\n }\n const start = result[i][0]\n const end = result[i][1]\n if (start === Infinity) {\n result[i][0] = 0\n }\n if (end === -Infinity) {\n result[i][1] = -1\n }\n\n const backwardDistance = this.root.nodeCacheBackward\n const forwardDistance = this.root.nodeCacheForward\n const overscanBackward = result[i][0] - backwardDistance\n const overscanForward = result[i][1] + forwardDistance\n result[i][0] = overscanBackward < 0 ? 0 : overscanBackward\n result[i][1] = overscanForward > column.length ? column.length - 1 : overscanForward\n\n // 列尾连续未测量节点纳入渲染区间,保证追加数据后能挂载并完成 measure\n let tailUnmeasuredStart = column.length\n for (let j = column.length - 1; j >= 0; j--) {\n if (!column[j].getState().layouted) {\n tailUnmeasuredStart = j\n } else {\n break\n }\n }\n if (tailUnmeasuredStart < column.length) {\n result[i][0] = Math.min(result[i][0], tailUnmeasuredStart)\n result[i][1] = Math.max(result[i][1], column.length - 1)\n }\n }\n\n const prevRange = this.getState().renderRange\n return isSameRenderRange(result, prevRange) ? prevRange : result\n }\n\n public pushNode(nodeIndex: number, col: number) {\n const { row: rowIndex, col: columnIndex } = getMatrixPosition(nodeIndex, col)\n const node = new Node(this.root, this, {\n childIndex: nodeIndex,\n order: rowIndex,\n col: columnIndex,\n height: this.defaultSize,\n })\n this.register(node)\n this.root.registerNode(node)\n }\n\n /** 仅扩展 columnMap / 注册 Node,不 setState;与 finalizePushNodesStateIfNeeded 配对 */\n public pushNodesStructuralOnly (count: number) {\n const { count: originalCount, col } = this\n for (let i = originalCount; i < originalCount + count; i++) {\n this.pushNode(i, col)\n }\n this.count += count\n this.root.lowerThresholdScrollTop = Infinity\n this._pendingPushFinalize = true\n }\n\n /** 在 commit 后同步 height、节点位置与 scrollHeight(见 WaterFlow useLayoutEffect) */\n public finalizePushNodesStateIfNeeded () {\n if (!this._pendingPushFinalize) return\n this._pendingPushFinalize = false\n // 同步 section state.height,避免与 maxColumnHeight 不一致导致 footer 错位\n this.setStateIn('height', this.maxColumnHeight)\n this.updateNodes()\n this.updateBehindSectionsPosition()\n // 立即更新 scrollHeight,避免防抖导致容器高度滞后引发往上抖动\n this.root.updateScrollHeight(true)\n if (this.isInRange) {\n this.setStateIn('renderRange', this.getNodeRenderRange())\n }\n // 扩展 Root 的 section 切片,保证多 FlowSection 时当前分组始终在渲染树内\n const [rStart, rEnd] = this.root.getState().renderRange\n const newStart = Math.min(rStart, this.order)\n const newEnd = Math.max(rEnd, this.order)\n if (newStart !== rStart || newEnd !== rEnd) {\n this.root.setStateIn('renderRange', [newStart, newEnd])\n }\n this.root.resetLowerReachEdgeAfterContentChange()\n }\n\n public pushNodes (count: number) {\n this.pushNodesStructuralOnly(count)\n this.finalizePushNodesStateIfNeeded()\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Root } from './root';
|
|
2
|
+
/** 快速滑动判定:像素/秒 */
|
|
3
|
+
export declare const WF_FAST_SCROLL_VELOCITY_PX_PER_S = 1000;
|
|
4
|
+
/** 快速滑动时 cache 倍数 */
|
|
5
|
+
export declare const WF_FAST_SCROLL_MULTIPLIER = 2;
|
|
6
|
+
/** 单边 Node 缓存上限 */
|
|
7
|
+
export declare const WF_FAST_SCROLL_NODE_CACHE_MAX = 30;
|
|
8
|
+
/** 无 scroll 视为停止的等待(ms) */
|
|
9
|
+
export declare const WF_SCROLL_STOP_MS = 300;
|
|
10
|
+
/** 停止后多久收敛回 base cache(ms) */
|
|
11
|
+
export declare const WF_CACHE_RESTORE_DELAY_MS = 2000;
|
|
12
|
+
/** 过短间隔忽略 velocity(ms) */
|
|
13
|
+
export declare const WF_VELOCITY_MIN_DELTA_MS = 16;
|
|
14
|
+
/** 过长间隔视为新一段滚动(ms) */
|
|
15
|
+
export declare const WF_VELOCITY_RESET_DELTA_MS = 500;
|
|
16
|
+
export type WaterFlowNodeCacheControl = {
|
|
17
|
+
onScrollSample: (scrollTop: number) => void;
|
|
18
|
+
dispose: () => void;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* 快速滑动时单边放大 Node 层 cache;停止后延迟收敛。
|
|
22
|
+
* 不暴露 props,内部常量可调参。
|
|
23
|
+
*/
|
|
24
|
+
export declare function createWaterFlowNodeCacheControl(root: Root, getBase: () => number): WaterFlowNodeCacheControl;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { requestAnimationFrame, cancelAnimationFrame } from '@tarojs/runtime';
|
|
2
|
+
|
|
3
|
+
/** 快速滑动判定:像素/秒 */
|
|
4
|
+
const WF_FAST_SCROLL_VELOCITY_PX_PER_S = 1000;
|
|
5
|
+
/** 快速滑动时 cache 倍数 */
|
|
6
|
+
const WF_FAST_SCROLL_MULTIPLIER = 2;
|
|
7
|
+
/** 单边 Node 缓存上限 */
|
|
8
|
+
const WF_FAST_SCROLL_NODE_CACHE_MAX = 30;
|
|
9
|
+
/** 无 scroll 视为停止的等待(ms) */
|
|
10
|
+
const WF_SCROLL_STOP_MS = 300;
|
|
11
|
+
/** 停止后多久收敛回 base cache(ms) */
|
|
12
|
+
const WF_CACHE_RESTORE_DELAY_MS = 2000;
|
|
13
|
+
/** 过短间隔忽略 velocity(ms) */
|
|
14
|
+
const WF_VELOCITY_MIN_DELTA_MS = 16;
|
|
15
|
+
/** 过长间隔视为新一段滚动(ms) */
|
|
16
|
+
const WF_VELOCITY_RESET_DELTA_MS = 500;
|
|
17
|
+
/**
|
|
18
|
+
* 快速滑动时单边放大 Node 层 cache;停止后延迟收敛。
|
|
19
|
+
* 不暴露 props,内部常量可调参。
|
|
20
|
+
*/
|
|
21
|
+
function createWaterFlowNodeCacheControl(root, getBase) {
|
|
22
|
+
let lastProcessedScrollTop = 0;
|
|
23
|
+
let lastProcessedTime = 0;
|
|
24
|
+
let rafScheduled = false;
|
|
25
|
+
let rafId = null;
|
|
26
|
+
let pendingScrollTop = 0;
|
|
27
|
+
let pendingTime = 0;
|
|
28
|
+
let scrollStopTimer = null;
|
|
29
|
+
let restoreTimer = null;
|
|
30
|
+
let disposed = false;
|
|
31
|
+
/** 快滑会话:停滚收敛或长间隔重置前,轻滑仍按滚动方向维持单边放大 cache */
|
|
32
|
+
let boostSessionActive = false;
|
|
33
|
+
function flushVelocity() {
|
|
34
|
+
if (disposed)
|
|
35
|
+
return;
|
|
36
|
+
rafId = null;
|
|
37
|
+
rafScheduled = false;
|
|
38
|
+
const st = pendingScrollTop;
|
|
39
|
+
const t = pendingTime;
|
|
40
|
+
const base = getBase();
|
|
41
|
+
if (lastProcessedTime === 0) {
|
|
42
|
+
lastProcessedScrollTop = st;
|
|
43
|
+
lastProcessedTime = t;
|
|
44
|
+
boostSessionActive = false;
|
|
45
|
+
root.setNodeCacheRange(base, base);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const dt = t - lastProcessedTime;
|
|
49
|
+
const delta = Math.abs(st - lastProcessedScrollTop);
|
|
50
|
+
if (dt < WF_VELOCITY_MIN_DELTA_MS) {
|
|
51
|
+
lastProcessedScrollTop = st;
|
|
52
|
+
lastProcessedTime = t;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (dt > WF_VELOCITY_RESET_DELTA_MS) {
|
|
56
|
+
lastProcessedScrollTop = st;
|
|
57
|
+
lastProcessedTime = t;
|
|
58
|
+
boostSessionActive = false;
|
|
59
|
+
root.setNodeCacheRange(base, base);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const velocity = (delta / dt) * 1000;
|
|
63
|
+
const boosted = base > 0 ? Math.min(base * WF_FAST_SCROLL_MULTIPLIER, WF_FAST_SCROLL_NODE_CACHE_MAX) : 0;
|
|
64
|
+
const forwardDown = st >= lastProcessedScrollTop;
|
|
65
|
+
let backward = base;
|
|
66
|
+
let forward = base;
|
|
67
|
+
if (base > 0) {
|
|
68
|
+
if (velocity > WF_FAST_SCROLL_VELOCITY_PX_PER_S) {
|
|
69
|
+
boostSessionActive = true;
|
|
70
|
+
}
|
|
71
|
+
if (boostSessionActive) {
|
|
72
|
+
if (forwardDown) {
|
|
73
|
+
forward = boosted;
|
|
74
|
+
backward = base;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
backward = boosted;
|
|
78
|
+
forward = base;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
root.setNodeCacheRange(backward, forward);
|
|
83
|
+
lastProcessedScrollTop = st;
|
|
84
|
+
lastProcessedTime = t;
|
|
85
|
+
}
|
|
86
|
+
function onScrollSample(scrollTop) {
|
|
87
|
+
if (disposed)
|
|
88
|
+
return;
|
|
89
|
+
pendingScrollTop = scrollTop;
|
|
90
|
+
pendingTime = Date.now();
|
|
91
|
+
if (!rafScheduled) {
|
|
92
|
+
rafScheduled = true;
|
|
93
|
+
rafId = requestAnimationFrame(flushVelocity);
|
|
94
|
+
}
|
|
95
|
+
if (scrollStopTimer != null) {
|
|
96
|
+
clearTimeout(scrollStopTimer);
|
|
97
|
+
scrollStopTimer = null;
|
|
98
|
+
}
|
|
99
|
+
if (restoreTimer != null) {
|
|
100
|
+
clearTimeout(restoreTimer);
|
|
101
|
+
restoreTimer = null;
|
|
102
|
+
}
|
|
103
|
+
scrollStopTimer = setTimeout(() => {
|
|
104
|
+
scrollStopTimer = null;
|
|
105
|
+
restoreTimer = setTimeout(() => {
|
|
106
|
+
restoreTimer = null;
|
|
107
|
+
if (disposed)
|
|
108
|
+
return;
|
|
109
|
+
boostSessionActive = false;
|
|
110
|
+
root.setNodeCacheRange(getBase(), getBase());
|
|
111
|
+
}, WF_CACHE_RESTORE_DELAY_MS);
|
|
112
|
+
}, WF_SCROLL_STOP_MS);
|
|
113
|
+
}
|
|
114
|
+
function dispose() {
|
|
115
|
+
disposed = true;
|
|
116
|
+
if (rafId != null) {
|
|
117
|
+
cancelAnimationFrame(rafId);
|
|
118
|
+
rafId = null;
|
|
119
|
+
}
|
|
120
|
+
rafScheduled = false;
|
|
121
|
+
if (scrollStopTimer != null) {
|
|
122
|
+
clearTimeout(scrollStopTimer);
|
|
123
|
+
scrollStopTimer = null;
|
|
124
|
+
}
|
|
125
|
+
if (restoreTimer != null) {
|
|
126
|
+
clearTimeout(restoreTimer);
|
|
127
|
+
restoreTimer = null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return { onScrollSample, dispose };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export { WF_CACHE_RESTORE_DELAY_MS, WF_FAST_SCROLL_MULTIPLIER, WF_FAST_SCROLL_NODE_CACHE_MAX, WF_FAST_SCROLL_VELOCITY_PX_PER_S, WF_SCROLL_STOP_MS, WF_VELOCITY_MIN_DELTA_MS, WF_VELOCITY_RESET_DELTA_MS, createWaterFlowNodeCacheControl };
|
|
134
|
+
//# sourceMappingURL=water-flow-node-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"water-flow-node-cache.js","sources":["../../../src/components/water-flow/water-flow-node-cache.ts"],"sourcesContent":["import { cancelAnimationFrame, requestAnimationFrame } from '@tarojs/runtime'\n\nimport type { Root } from './root'\n\n/** 快速滑动判定:像素/秒 */\nexport const WF_FAST_SCROLL_VELOCITY_PX_PER_S = 1000\n/** 快速滑动时 cache 倍数 */\nexport const WF_FAST_SCROLL_MULTIPLIER = 2\n/** 单边 Node 缓存上限 */\nexport const WF_FAST_SCROLL_NODE_CACHE_MAX = 30\n/** 无 scroll 视为停止的等待(ms) */\nexport const WF_SCROLL_STOP_MS = 300\n/** 停止后多久收敛回 base cache(ms) */\nexport const WF_CACHE_RESTORE_DELAY_MS = 2000\n/** 过短间隔忽略 velocity(ms) */\nexport const WF_VELOCITY_MIN_DELTA_MS = 16\n/** 过长间隔视为新一段滚动(ms) */\nexport const WF_VELOCITY_RESET_DELTA_MS = 500\n\nexport type WaterFlowNodeCacheControl = {\n onScrollSample: (scrollTop: number) => void\n dispose: () => void\n}\n\n/**\n * 快速滑动时单边放大 Node 层 cache;停止后延迟收敛。\n * 不暴露 props,内部常量可调参。\n */\nexport function createWaterFlowNodeCacheControl (\n root: Root,\n getBase: () => number\n): WaterFlowNodeCacheControl {\n let lastProcessedScrollTop = 0\n let lastProcessedTime = 0\n let rafScheduled = false\n let rafId: number | null = null\n let pendingScrollTop = 0\n let pendingTime = 0\n let scrollStopTimer: ReturnType<typeof setTimeout> | null = null\n let restoreTimer: ReturnType<typeof setTimeout> | null = null\n let disposed = false\n /** 快滑会话:停滚收敛或长间隔重置前,轻滑仍按滚动方向维持单边放大 cache */\n let boostSessionActive = false\n\n function flushVelocity () {\n if (disposed) return\n rafId = null\n rafScheduled = false\n const st = pendingScrollTop\n const t = pendingTime\n const base = getBase()\n\n if (lastProcessedTime === 0) {\n lastProcessedScrollTop = st\n lastProcessedTime = t\n boostSessionActive = false\n root.setNodeCacheRange(base, base)\n return\n }\n\n const dt = t - lastProcessedTime\n const delta = Math.abs(st - lastProcessedScrollTop)\n\n if (dt < WF_VELOCITY_MIN_DELTA_MS) {\n lastProcessedScrollTop = st\n lastProcessedTime = t\n return\n }\n\n if (dt > WF_VELOCITY_RESET_DELTA_MS) {\n lastProcessedScrollTop = st\n lastProcessedTime = t\n boostSessionActive = false\n root.setNodeCacheRange(base, base)\n return\n }\n\n const velocity = (delta / dt) * 1000\n const boosted =\n base > 0 ? Math.min(base * WF_FAST_SCROLL_MULTIPLIER, WF_FAST_SCROLL_NODE_CACHE_MAX) : 0\n const forwardDown = st >= lastProcessedScrollTop\n\n let backward = base\n let forward = base\n if (base > 0) {\n if (velocity > WF_FAST_SCROLL_VELOCITY_PX_PER_S) {\n boostSessionActive = true\n }\n if (boostSessionActive) {\n if (forwardDown) {\n forward = boosted\n backward = base\n } else {\n backward = boosted\n forward = base\n }\n }\n }\n\n root.setNodeCacheRange(backward, forward)\n lastProcessedScrollTop = st\n lastProcessedTime = t\n }\n\n function onScrollSample (scrollTop: number) {\n if (disposed) return\n pendingScrollTop = scrollTop\n pendingTime = Date.now()\n if (!rafScheduled) {\n rafScheduled = true\n rafId = requestAnimationFrame(flushVelocity) as unknown as number\n }\n\n if (scrollStopTimer != null) {\n clearTimeout(scrollStopTimer)\n scrollStopTimer = null\n }\n if (restoreTimer != null) {\n clearTimeout(restoreTimer)\n restoreTimer = null\n }\n\n scrollStopTimer = setTimeout(() => {\n scrollStopTimer = null\n restoreTimer = setTimeout(() => {\n restoreTimer = null\n if (disposed) return\n boostSessionActive = false\n root.setNodeCacheRange(getBase(), getBase())\n }, WF_CACHE_RESTORE_DELAY_MS)\n }, WF_SCROLL_STOP_MS)\n }\n\n function dispose () {\n disposed = true\n if (rafId != null) {\n cancelAnimationFrame(rafId)\n rafId = null\n }\n rafScheduled = false\n if (scrollStopTimer != null) {\n clearTimeout(scrollStopTimer)\n scrollStopTimer = null\n }\n if (restoreTimer != null) {\n clearTimeout(restoreTimer)\n restoreTimer = null\n }\n }\n\n return { onScrollSample, dispose }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __rest } from 'tslib';
|
|
2
2
|
import { View, ScrollView } from '@tarojs/components';
|
|
3
3
|
import Taro, { nextTick } from '@tarojs/taro';
|
|
4
|
-
import { useContext, useRef, useCallback, useId, useMemo, Children, cloneElement,
|
|
4
|
+
import { useContext, useRef, useCallback, useId, useMemo, useEffect, Children, cloneElement, useLayoutEffect, createElement, forwardRef } from 'react';
|
|
5
5
|
import '../../utils/index.js';
|
|
6
6
|
import { ScrollElementContextOrFallback } from '../../utils/scrollElementContext.js';
|
|
7
7
|
import { useMeasureStartOffset } from '../list/hooks/useMeasureStartOffset.js';
|
|
@@ -12,6 +12,7 @@ import { Section } from './section.js';
|
|
|
12
12
|
import { useMemoizedFn } from './use-memoized-fn.js';
|
|
13
13
|
import { useObservedAttr } from './use-observed-attr.js';
|
|
14
14
|
import { getSysInfo, isH5, isWeapp } from './utils.js';
|
|
15
|
+
import { createWaterFlowNodeCacheControl } from './water-flow-node-cache.js';
|
|
15
16
|
import { getScrollViewContextNode } from '../../utils/dom.js';
|
|
16
17
|
import { debounce } from '../../utils/lodash.js';
|
|
17
18
|
|
|
@@ -85,13 +86,24 @@ const InnerWaterFlow = (_a, ref) => {
|
|
|
85
86
|
const scrollHeight$ = useObservedAttr(root, 'scrollHeight');
|
|
86
87
|
const renderRange$ = useObservedAttr(root, 'renderRange');
|
|
87
88
|
const refEventOrig = useRef();
|
|
89
|
+
const nodeCacheCtlRef = useRef(null);
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
const ctl = createWaterFlowNodeCacheControl(root, () => root.cacheCount);
|
|
92
|
+
nodeCacheCtlRef.current = ctl;
|
|
93
|
+
return () => {
|
|
94
|
+
ctl.dispose();
|
|
95
|
+
nodeCacheCtlRef.current = null;
|
|
96
|
+
};
|
|
97
|
+
}, [root]);
|
|
88
98
|
/**
|
|
89
99
|
* 滚动事件
|
|
90
100
|
*/
|
|
91
101
|
const handleScroll = useMemoizedFn((ev) => {
|
|
102
|
+
var _a;
|
|
92
103
|
refEventOrig.current = ev;
|
|
93
|
-
root.sections.forEach((section) => section.getNodeRenderRange());
|
|
94
104
|
const { scrollTop } = ev.detail;
|
|
105
|
+
(_a = nodeCacheCtlRef.current) === null || _a === void 0 ? void 0 : _a.onScrollSample(scrollTop);
|
|
106
|
+
root.sections.forEach((section) => section.getNodeRenderRange());
|
|
95
107
|
const scrollDirection = root.getState().scrollOffset < scrollTop ? 'forward' : 'backward';
|
|
96
108
|
root.setStateBatch({
|
|
97
109
|
scrollDirection: scrollDirection,
|
|
@@ -114,7 +126,7 @@ const InnerWaterFlow = (_a, ref) => {
|
|
|
114
126
|
if (section) {
|
|
115
127
|
const originalCount = section.count;
|
|
116
128
|
if (childCount > originalCount) {
|
|
117
|
-
section.
|
|
129
|
+
section.pushNodesStructuralOnly(childCount - originalCount);
|
|
118
130
|
}
|
|
119
131
|
}
|
|
120
132
|
else {
|
|
@@ -130,6 +142,18 @@ const InnerWaterFlow = (_a, ref) => {
|
|
|
130
142
|
return cloneElement(child, { section, key: `${props.id}-${order}` });
|
|
131
143
|
})) === null || _a === void 0 ? void 0 : _a.slice(start, end + 1);
|
|
132
144
|
}, [renderRange$[0], renderRange$[1], children, root, props.id]);
|
|
145
|
+
/** 配对 pushNodesStructuralOnly:在 layout 阶段完成 Section 状态,避免 useMemo 内 setState 告警 */
|
|
146
|
+
useLayoutEffect(() => {
|
|
147
|
+
Children.forEach(children, (child, order) => {
|
|
148
|
+
var _a;
|
|
149
|
+
if (Object.is(child, null)) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const sectionProps = child.props;
|
|
153
|
+
const sectionId = sectionProps.id || `section-${order}`;
|
|
154
|
+
(_a = root.findSection(sectionId)) === null || _a === void 0 ? void 0 : _a.finalizePushNodesStateIfNeeded();
|
|
155
|
+
});
|
|
156
|
+
}, [children, root]);
|
|
133
157
|
const scrollTo = useMemoizedFn((scrollOffset = 0) => {
|
|
134
158
|
var _a;
|
|
135
159
|
scrollOffset = Math.max(0, scrollOffset);
|
|
@@ -255,7 +279,7 @@ const InnerWaterFlow = (_a, ref) => {
|
|
|
255
279
|
}
|
|
256
280
|
const getStartOffset = () => { var _a; return (isWeapp ? effectiveStartOffsetRef.current : ((_a = startOffsetRef.current) !== null && _a !== void 0 ? _a : 0)); };
|
|
257
281
|
const handler = (e) => {
|
|
258
|
-
var _a, _b, _c, _d, _e;
|
|
282
|
+
var _a, _b, _c, _d, _e, _f;
|
|
259
283
|
const scrollTop = isWeapp
|
|
260
284
|
? ((_e = (_b = (_a = e === null || e === void 0 ? void 0 : e.target) === null || _a === void 0 ? void 0 : _a.scrollTop) !== null && _b !== void 0 ? _b : (_d = (_c = e === null || e === void 0 ? void 0 : e.mpEvent) === null || _c === void 0 ? void 0 : _c.detail) === null || _d === void 0 ? void 0 : _d.scrollTop) !== null && _e !== void 0 ? _e : 0)
|
|
261
285
|
: target.scrollTop;
|
|
@@ -263,6 +287,7 @@ const InnerWaterFlow = (_a, ref) => {
|
|
|
263
287
|
const effectiveOffset = Math.max(0, offset);
|
|
264
288
|
const prevOffset = root.getState().scrollOffset;
|
|
265
289
|
const scrollDirection = prevOffset < effectiveOffset ? 'forward' : 'backward';
|
|
290
|
+
(_f = nodeCacheCtlRef.current) === null || _f === void 0 ? void 0 : _f.onScrollSample(effectiveOffset);
|
|
266
291
|
root.sections.forEach((section) => section.getNodeRenderRange());
|
|
267
292
|
root.setStateBatch({
|
|
268
293
|
scrollDirection,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"water-flow.js","sources":["../../../src/components/water-flow/water-flow.ts"],"sourcesContent":["import { BaseEventOrig, ScrollView, ScrollViewProps, View } from '@tarojs/components'\nimport Taro, { nextTick } from '@tarojs/taro'\nimport {\n Children,\n cloneElement,\n createElement,\n forwardRef,\n PropsWithChildren,\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n} from 'react'\n\nimport { debounce, getScrollViewContextNode } from '../../utils'\nimport {\n type ScrollElementContextValueShape,\n ScrollElementContextOrFallback,\n} from '../../utils/scrollElementContext'\nimport { useMeasureStartOffset } from '../list/hooks/useMeasureStartOffset'\nimport { useMeasureStartOffsetWeapp } from '../list/hooks/useMeasureStartOffsetWeapp'\nimport { useScrollParentAutoFind } from '../list/hooks/useScrollParentAutoFind'\nimport { _FlowSectionProps } from './flow-section'\nimport { Root, RootEvents } from './root'\nimport { Section } from './section'\nimport { useMemoizedFn } from './use-memoized-fn'\nimport { useObservedAttr } from './use-observed-attr'\nimport { getSysInfo, isH5, isWeapp } from './utils'\n\nimport type { ScrollDirection, WaterFlowProps } from './interface'\n\ngetSysInfo()\n\nconst InnerWaterFlow = (\n { children, ...props }: PropsWithChildren<WaterFlowProps>,\n ref: React.ForwardedRef<HTMLElement>\n) => {\n const {\n id,\n style = {},\n className,\n cacheCount = 1,\n onScrollToUpper,\n onScrollToLower,\n upperThresholdCount,\n lowerThresholdCount,\n scrollIntoView,\n nestedScroll,\n scrollElement,\n startOffset,\n containerHeight,\n onScrollHeightChange,\n onScrollIntoViewComplete,\n ...rest\n } = props\n const flowType = nestedScroll === true ? 'nested' : 'default'\n // 从 ScrollElementContext 获取 scrollRef(List/ScrollView 内嵌时提供);无 Context 时兜底为 fallback\n const scrollElementCtx = useContext(ScrollElementContextOrFallback) as ScrollElementContextValueShape | null\n const contentWrapperRef = useRef<HTMLDivElement>(null)\n const setContainerRef = useCallback(\n (el: HTMLElement | null) => {\n (contentWrapperRef as React.MutableRefObject<HTMLElement | null>).current = el\n if (typeof ref === 'function') ref(el)\n else if (ref) (ref as React.MutableRefObject<HTMLElement | null>).current = el\n },\n [ref]\n )\n const defaultId = useId().replace(/:/g, '')\n const contentId = useMemo(() => id ?? defaultId, [id, defaultId])\n const needAutoFind =\n flowType === 'nested' &&\n !scrollElement &&\n !scrollElementCtx?.scrollRef &&\n (isH5 || isWeapp)\n const { scrollParentRef: autoFoundRef, status: autoFindStatus } = useScrollParentAutoFind(\n contentWrapperRef,\n { enabled: !!needAutoFind, isHorizontal: false, contentId: isWeapp ? contentId : undefined }\n )\n const effectiveScrollElement =\n scrollElement ??\n scrollElementCtx?.scrollRef ??\n (needAutoFind && autoFindStatus === 'found' ? autoFoundRef : null)\n const ctxStart = scrollElementCtx?.startOffset\n const hasExplicitStartOffset = ctxStart != null && ctxStart > 0\n const needMeasureStartOffset =\n flowType === 'nested' &&\n effectiveScrollElement &&\n isH5 &&\n startOffset == null &&\n !hasExplicitStartOffset\n const needMeasureStartOffsetWeapp =\n flowType === 'nested' &&\n effectiveScrollElement &&\n isWeapp &&\n startOffset == null &&\n !hasExplicitStartOffset\n const measuredStartOffset = useMeasureStartOffset(\n effectiveScrollElement ?? { current: null },\n contentWrapperRef,\n { enabled: !!needMeasureStartOffset, isHorizontal: false }\n )\n const effectiveStartOffsetRef = useRef(0)\n const measuredStartOffsetWeapp = useMeasureStartOffsetWeapp(\n effectiveScrollElement ?? { current: null },\n contentId,\n { enabled: !!needMeasureStartOffsetWeapp, isHorizontal: false, startOffsetRef: effectiveStartOffsetRef }\n )\n const effectiveStartOffset =\n startOffset ??\n (ctxStart != null && ctxStart > 0 ? ctxStart : null) ??\n measuredStartOffset ??\n measuredStartOffsetWeapp ??\n 0\n\n const effectiveContainerHeight = containerHeight ?? scrollElementCtx?.containerHeight\n\n const startOffsetRef = useRef(effectiveStartOffset)\n const containerHeightRef = useRef(effectiveContainerHeight)\n const lastReportedHeightRef = useRef<number>(0)\n startOffsetRef.current = effectiveStartOffset\n if (!needMeasureStartOffsetWeapp) {\n effectiveStartOffsetRef.current = effectiveStartOffset\n }\n containerHeightRef.current = effectiveContainerHeight\n\n const useScrollElementMode =\n flowType === 'nested' && !!(effectiveScrollElement && (isH5 || isWeapp))\n if (flowType === 'nested' && !effectiveScrollElement && (isH5 || isWeapp) && autoFindStatus === 'not-found') {\n // eslint-disable-next-line no-console\n console.warn('[WaterFlow] nestedScroll 模式但无 scrollElement(props/Context/自动查找),回退为 default,将渲染自有 ScrollView')\n }\n /**\n * 初始化数据模型\n */\n const root = useMemo(() => {\n return new Root({\n id: contentId,\n cacheCount,\n upperThresholdCount,\n lowerThresholdCount,\n skipContainerMeasure: useScrollElementMode || (!!needAutoFind && autoFindStatus === 'pending'),\n })\n }, [contentId, cacheCount, upperThresholdCount, lowerThresholdCount, useScrollElementMode, needAutoFind, autoFindStatus])\n const isScrolling$ = useObservedAttr(root, 'isScrolling')\n const scrollHeight$ = useObservedAttr(root, 'scrollHeight')\n const renderRange$ = useObservedAttr(root, 'renderRange')\n const refEventOrig = useRef<BaseEventOrig>()\n\n /**\n * 滚动事件\n */\n const handleScroll = useMemoizedFn((ev: BaseEventOrig<ScrollViewProps.onScrollDetail>) => {\n refEventOrig.current = ev\n root.sections.forEach((section) => section.getNodeRenderRange())\n const { scrollTop } = ev.detail\n const scrollDirection: ScrollDirection = root.getState().scrollOffset < scrollTop ? 'forward' : 'backward'\n root.setStateBatch({\n scrollDirection: scrollDirection,\n scrollOffset: scrollTop,\n isScrolling: true,\n })\n })\n\n const sections = useMemo(() => {\n const [start, end] = renderRange$\n return Children.map(children, (child: ReactElement<PropsWithChildren<_FlowSectionProps>>, order) => {\n if (Object.is(child, null)) {\n return null\n }\n const sectionProps = child.props\n const sectionId = sectionProps.id || `section-${order}`\n const childCount = Children.count(sectionProps.children)\n let section = root.findSection(sectionId)\n if (section) {\n const originalCount = section.count\n if (childCount > originalCount) {\n section.pushNodes(childCount - originalCount)\n }\n } else {\n section = new Section(root, {\n id: sectionId,\n order,\n col: sectionProps.column ?? 1,\n rowGap: sectionProps.rowGap || 0,\n columnGap: sectionProps.columnGap || 0,\n count: Children.count(sectionProps.children),\n })\n }\n\n return cloneElement(child, { section, key: `${props.id}-${order}` })\n })?.slice(start, end + 1)\n }, [renderRange$[0], renderRange$[1], children, root, props.id])\n\n const scrollTo = useMemoizedFn((scrollOffset = 0) => {\n scrollOffset = Math.max(0, scrollOffset)\n if (root.getState().scrollOffset === scrollOffset) return\n if (useScrollElementMode && effectiveScrollElement?.current) {\n const el = effectiveScrollElement.current as any\n const startOff = isWeapp ? effectiveStartOffsetRef.current : (startOffsetRef.current ?? 0)\n const scrollTarget = scrollOffset + startOff\n if (isH5) {\n el.scrollTo({ top: scrollTarget })\n } else if (isWeapp) {\n const scrollViewId = el.id || `_wf_${contentId}`\n if (!el.id) el.id = scrollViewId\n getScrollViewContextNode(`#${scrollViewId}`).then((node: any) => {\n node?.scrollTo?.({ top: scrollTarget, animated: true, duration: 300 })\n })\n }\n root.setStateBatch({ scrollOffset, isScrolling: true })\n root.sections.forEach((s) => s.getNodeRenderRange())\n return\n }\n getScrollViewContextNode(`#${root.id}`).then((node: any) => {\n node.scrollTo({\n animated: true,\n duration: 300,\n top: scrollOffset,\n })\n })\n })\n\n const resetScrolling = useMemoizedFn(() => {\n root.setStateIn('isScrolling', false)\n })\n\n const debouncedResetScrolling = debounce(resetScrolling)\n\n useEffect(() => {\n debouncedResetScrolling()\n }, [isScrolling$])\n\n /**\n * 处理滚动阈值\n * root 需入参:autoFind 从 pending→found 时 root 会重建,必须对新 root 重新订阅\n */\n useEffect(() => {\n const disposers = [\n root.sub(\n RootEvents.ReachUpperThreshold,\n debounce(() => {\n onScrollToUpper?.(refEventOrig.current!)\n })\n ),\n root.sub(\n RootEvents.ReachLowerThreshold,\n debounce(() => {\n onScrollToLower?.(refEventOrig.current!)\n })\n ),\n ]\n return () => {\n disposers.forEach((disposer) => {\n disposer()\n })\n }\n }, [root, onScrollToUpper, onScrollToLower])\n\n /**\n * 处理 scrollIntoView\n * 竞态:快速切换目标时,取消前一次滚动,避免后发先至\n */\n useEffect(() => {\n let cancelled = false\n handleScrollIntoView()\n async function handleScrollIntoView() {\n if (!scrollIntoView) return\n const targetNode = root.findNode(scrollIntoView)\n if (!targetNode) {\n nextTick(() => { if (!cancelled) onScrollIntoViewComplete?.() })\n return\n }\n const targetSection = targetNode.section\n const doScroll = () => {\n if (cancelled) return\n scrollTo(targetNode.getState().scrollTop)\n if (cancelled) return\n nextTick(() => { if (!cancelled) onScrollIntoViewComplete?.() })\n }\n if (!targetSection.getState().layouted) {\n const order = targetSection.order\n root.setStateIn('renderRange', [\n Math.min(renderRange$[0], order),\n Math.max(renderRange$[1], order),\n ])\n nextTick(async () => {\n await targetNode.section.layoutedSignal.promise\n if (cancelled) return\n doScroll()\n })\n return\n }\n await targetSection.layoutedSignal.promise\n if (cancelled) return\n doScroll()\n }\n return () => { cancelled = true }\n }, [scrollIntoView, renderRange$[0], renderRange$[1], onScrollIntoViewComplete])\n\n // scrollElement 模式下监听外部滚动,更新 root.scrollOffset;effectiveStartOffset 变化时重新同步;内嵌时 scrollRef 可能尚未就绪,需重试\n useEffect(() => {\n if (!useScrollElementMode || !effectiveScrollElement) return\n\n let cancelled = false\n let teardown: (() => void) | null = null\n const maxRetries = 20\n\n const tryAttach = (retryCount = 0) => {\n if (cancelled) return\n const target = effectiveScrollElement.current as any\n if (!target) {\n if (retryCount < maxRetries) {\n setTimeout(() => tryAttach(retryCount + 1), 50)\n }\n return\n }\n\n const getStartOffset = () => (isWeapp ? effectiveStartOffsetRef.current : (startOffsetRef.current ?? 0))\n\n const handler = (e?: any) => {\n const scrollTop = isWeapp\n ? (e?.target?.scrollTop ?? e?.mpEvent?.detail?.scrollTop ?? 0)\n : target.scrollTop\n const offset = scrollTop - getStartOffset()\n const effectiveOffset = Math.max(0, offset)\n const prevOffset = root.getState().scrollOffset\n const scrollDirection: ScrollDirection = prevOffset < effectiveOffset ? 'forward' : 'backward'\n\n root.sections.forEach((section) => section.getNodeRenderRange())\n root.setStateBatch({\n scrollDirection,\n scrollOffset: effectiveOffset,\n isScrolling: true,\n })\n }\n\n if (isWeapp) {\n if (!target.id) target.id = `_wf_${contentId}`\n const scrollViewId = target.id\n const instance = Taro.getCurrentInstance()\n const query = instance?.page\n ? Taro.createSelectorQuery().in(instance.page as any)\n : Taro.createSelectorQuery()\n query.select(`#${scrollViewId}`).scrollOffset().exec((res) => {\n if (cancelled) return\n const info = res?.[0]\n if (info) {\n const scrollTopVal = info.scrollTop ?? 0\n const initialOffset = Math.max(0, scrollTopVal - getStartOffset())\n root.setStateBatch({ scrollOffset: initialOffset, isScrolling: true })\n root.sections.forEach((s) => s.getNodeRenderRange())\n }\n })\n } else {\n const initialOffset = Math.max(0, target.scrollTop - getStartOffset())\n root.setStateBatch({ scrollOffset: initialOffset, isScrolling: true })\n root.sections.forEach((s) => s.getNodeRenderRange())\n }\n\n target.addEventListener('scroll', handler, isWeapp ? undefined : { passive: true })\n teardown = () => target.removeEventListener('scroll', handler)\n }\n\n tryAttach()\n return () => {\n cancelled = true\n teardown?.()\n }\n }, [useScrollElementMode, effectiveScrollElement, root, effectiveStartOffset, contentId])\n\n // scrollHeight 变化时回调(props 优先,其次从 Context),便于 List 动高联动;防抖 150ms 上报\n const reportHeight = onScrollHeightChange ?? scrollElementCtx?.reportNestedHeightChange\n useEffect(() => {\n if (!reportHeight || scrollHeight$ <= 0) return\n const timer = setTimeout(() => {\n if (Math.abs(lastReportedHeightRef.current - scrollHeight$) < 1) return\n lastReportedHeightRef.current = scrollHeight$\n reportHeight(scrollHeight$)\n }, 150)\n return () => clearTimeout(timer)\n }, [scrollHeight$, reportHeight])\n\n // scrollElement 模式下监听容器尺寸:H5 用 ResizeObserver,小程序用 createSelectorQuery 轮询\n useEffect(() => {\n if (!useScrollElementMode || !effectiveScrollElement) return\n const el = effectiveScrollElement.current as any\n if (!el) return\n\n if (isWeapp) {\n if (!el.id) el.id = `_wf_${contentId}`\n const scrollViewId = el.id\n const measure = () => {\n const instance = Taro.getCurrentInstance()\n const query = instance?.page\n ? Taro.createSelectorQuery().in(instance.page as any)\n : Taro.createSelectorQuery()\n query.select(`#${scrollViewId}`).boundingClientRect().exec((res) => {\n const rect = res?.[0]\n if (rect && rect.height > 0 && rect.width > 0) {\n const height = containerHeightRef.current ?? rect.height\n root.setStateIn('containerSize', { width: rect.width, height })\n }\n })\n }\n measure()\n const interval = setInterval(measure, 150)\n return () => clearInterval(interval)\n }\n\n if (typeof ResizeObserver === 'undefined') return\n const update = () => {\n const height = containerHeightRef.current ?? el.clientHeight\n const width = el.clientWidth\n if (height > 0 && width > 0) {\n root.setStateIn('containerSize', { width, height })\n }\n }\n update()\n const ro = new ResizeObserver(update)\n ro.observe(el)\n return () => ro.disconnect()\n }, [useScrollElementMode, effectiveScrollElement, root, effectiveContainerHeight, contentId])\n\n // scrollElement 模式下只渲染内容 View(不渲染 ScrollView);内容高度须为 scrollHeight 以支持父级滚动;needAutoFind 且 pending 时 probe 渲染以便查找父容器\n const renderView =\n useScrollElementMode || (!!needAutoFind && autoFindStatus === 'pending')\n if (renderView) {\n return createElement(\n View,\n {\n ref: setContainerRef as any,\n id: root.id,\n style: {\n ...style,\n width: '100%',\n position: 'relative',\n height: scrollHeight$,\n pointerEvents: isScrolling$ ? 'none' : 'auto',\n },\n className,\n },\n sections\n )\n }\n\n return createElement(\n ScrollView,\n {\n id: root.id,\n style: {\n WebkitOverflowScrolling: 'touch',\n overflow: 'auto',\n ...style,\n },\n className,\n scrollY: true,\n onScroll: handleScroll,\n ...rest,\n },\n createElement(\n View,\n {\n ref: setContainerRef as any,\n id: 'waterflow-root',\n style: {\n width: '100%',\n position: 'relative',\n height: scrollHeight$,\n pointerEvents: isScrolling$ ? 'none' : 'auto',\n },\n },\n sections\n )\n )\n}\n\nexport const WaterFlow = forwardRef<HTMLElement, PropsWithChildren<WaterFlowProps>>(InnerWaterFlow)\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"water-flow.js","sources":["../../../src/components/water-flow/water-flow.ts"],"sourcesContent":["import { BaseEventOrig, ScrollView, ScrollViewProps, View } from '@tarojs/components'\nimport Taro, { nextTick } from '@tarojs/taro'\nimport {\n Children,\n cloneElement,\n createElement,\n forwardRef,\n PropsWithChildren,\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n} from 'react'\n\nimport { debounce, getScrollViewContextNode } from '../../utils'\nimport {\n type ScrollElementContextValueShape,\n ScrollElementContextOrFallback,\n} from '../../utils/scrollElementContext'\nimport { useMeasureStartOffset } from '../list/hooks/useMeasureStartOffset'\nimport { useMeasureStartOffsetWeapp } from '../list/hooks/useMeasureStartOffsetWeapp'\nimport { useScrollParentAutoFind } from '../list/hooks/useScrollParentAutoFind'\nimport { _FlowSectionProps } from './flow-section'\nimport { Root, RootEvents } from './root'\nimport { Section } from './section'\nimport { useMemoizedFn } from './use-memoized-fn'\nimport { useObservedAttr } from './use-observed-attr'\nimport { getSysInfo, isH5, isWeapp } from './utils'\nimport { createWaterFlowNodeCacheControl } from './water-flow-node-cache'\n\nimport type { ScrollDirection, WaterFlowProps } from './interface'\n\ngetSysInfo()\n\nconst InnerWaterFlow = (\n { children, ...props }: PropsWithChildren<WaterFlowProps>,\n ref: React.ForwardedRef<HTMLElement>\n) => {\n const {\n id,\n style = {},\n className,\n cacheCount = 1,\n onScrollToUpper,\n onScrollToLower,\n upperThresholdCount,\n lowerThresholdCount,\n scrollIntoView,\n nestedScroll,\n scrollElement,\n startOffset,\n containerHeight,\n onScrollHeightChange,\n onScrollIntoViewComplete,\n ...rest\n } = props\n const flowType = nestedScroll === true ? 'nested' : 'default'\n // 从 ScrollElementContext 获取 scrollRef(List/ScrollView 内嵌时提供);无 Context 时兜底为 fallback\n const scrollElementCtx = useContext(ScrollElementContextOrFallback) as ScrollElementContextValueShape | null\n const contentWrapperRef = useRef<HTMLDivElement>(null)\n const setContainerRef = useCallback(\n (el: HTMLElement | null) => {\n (contentWrapperRef as React.MutableRefObject<HTMLElement | null>).current = el\n if (typeof ref === 'function') ref(el)\n else if (ref) (ref as React.MutableRefObject<HTMLElement | null>).current = el\n },\n [ref]\n )\n const defaultId = useId().replace(/:/g, '')\n const contentId = useMemo(() => id ?? defaultId, [id, defaultId])\n const needAutoFind =\n flowType === 'nested' &&\n !scrollElement &&\n !scrollElementCtx?.scrollRef &&\n (isH5 || isWeapp)\n const { scrollParentRef: autoFoundRef, status: autoFindStatus } = useScrollParentAutoFind(\n contentWrapperRef,\n { enabled: !!needAutoFind, isHorizontal: false, contentId: isWeapp ? contentId : undefined }\n )\n const effectiveScrollElement =\n scrollElement ??\n scrollElementCtx?.scrollRef ??\n (needAutoFind && autoFindStatus === 'found' ? autoFoundRef : null)\n const ctxStart = scrollElementCtx?.startOffset\n const hasExplicitStartOffset = ctxStart != null && ctxStart > 0\n const needMeasureStartOffset =\n flowType === 'nested' &&\n effectiveScrollElement &&\n isH5 &&\n startOffset == null &&\n !hasExplicitStartOffset\n const needMeasureStartOffsetWeapp =\n flowType === 'nested' &&\n effectiveScrollElement &&\n isWeapp &&\n startOffset == null &&\n !hasExplicitStartOffset\n const measuredStartOffset = useMeasureStartOffset(\n effectiveScrollElement ?? { current: null },\n contentWrapperRef,\n { enabled: !!needMeasureStartOffset, isHorizontal: false }\n )\n const effectiveStartOffsetRef = useRef(0)\n const measuredStartOffsetWeapp = useMeasureStartOffsetWeapp(\n effectiveScrollElement ?? { current: null },\n contentId,\n { enabled: !!needMeasureStartOffsetWeapp, isHorizontal: false, startOffsetRef: effectiveStartOffsetRef }\n )\n const effectiveStartOffset =\n startOffset ??\n (ctxStart != null && ctxStart > 0 ? ctxStart : null) ??\n measuredStartOffset ??\n measuredStartOffsetWeapp ??\n 0\n\n const effectiveContainerHeight = containerHeight ?? scrollElementCtx?.containerHeight\n\n const startOffsetRef = useRef(effectiveStartOffset)\n const containerHeightRef = useRef(effectiveContainerHeight)\n const lastReportedHeightRef = useRef<number>(0)\n startOffsetRef.current = effectiveStartOffset\n if (!needMeasureStartOffsetWeapp) {\n effectiveStartOffsetRef.current = effectiveStartOffset\n }\n containerHeightRef.current = effectiveContainerHeight\n\n const useScrollElementMode =\n flowType === 'nested' && !!(effectiveScrollElement && (isH5 || isWeapp))\n if (flowType === 'nested' && !effectiveScrollElement && (isH5 || isWeapp) && autoFindStatus === 'not-found') {\n // eslint-disable-next-line no-console\n console.warn('[WaterFlow] nestedScroll 模式但无 scrollElement(props/Context/自动查找),回退为 default,将渲染自有 ScrollView')\n }\n /**\n * 初始化数据模型\n */\n const root = useMemo(() => {\n return new Root({\n id: contentId,\n cacheCount,\n upperThresholdCount,\n lowerThresholdCount,\n skipContainerMeasure: useScrollElementMode || (!!needAutoFind && autoFindStatus === 'pending'),\n })\n }, [contentId, cacheCount, upperThresholdCount, lowerThresholdCount, useScrollElementMode, needAutoFind, autoFindStatus])\n const isScrolling$ = useObservedAttr(root, 'isScrolling')\n const scrollHeight$ = useObservedAttr(root, 'scrollHeight')\n const renderRange$ = useObservedAttr(root, 'renderRange')\n const refEventOrig = useRef<BaseEventOrig>()\n const nodeCacheCtlRef = useRef<ReturnType<typeof createWaterFlowNodeCacheControl> | null>(null)\n\n useEffect(() => {\n const ctl = createWaterFlowNodeCacheControl(root, () => root.cacheCount)\n nodeCacheCtlRef.current = ctl\n return () => {\n ctl.dispose()\n nodeCacheCtlRef.current = null\n }\n }, [root])\n\n /**\n * 滚动事件\n */\n const handleScroll = useMemoizedFn((ev: BaseEventOrig<ScrollViewProps.onScrollDetail>) => {\n refEventOrig.current = ev\n const { scrollTop } = ev.detail\n nodeCacheCtlRef.current?.onScrollSample(scrollTop)\n root.sections.forEach((section) => section.getNodeRenderRange())\n const scrollDirection: ScrollDirection = root.getState().scrollOffset < scrollTop ? 'forward' : 'backward'\n root.setStateBatch({\n scrollDirection: scrollDirection,\n scrollOffset: scrollTop,\n isScrolling: true,\n })\n })\n\n const sections = useMemo(() => {\n const [start, end] = renderRange$\n return Children.map(children, (child: ReactElement<PropsWithChildren<_FlowSectionProps>>, order) => {\n if (Object.is(child, null)) {\n return null\n }\n const sectionProps = child.props\n const sectionId = sectionProps.id || `section-${order}`\n const childCount = Children.count(sectionProps.children)\n let section = root.findSection(sectionId)\n if (section) {\n const originalCount = section.count\n if (childCount > originalCount) {\n section.pushNodesStructuralOnly(childCount - originalCount)\n }\n } else {\n section = new Section(root, {\n id: sectionId,\n order,\n col: sectionProps.column ?? 1,\n rowGap: sectionProps.rowGap || 0,\n columnGap: sectionProps.columnGap || 0,\n count: Children.count(sectionProps.children),\n })\n }\n\n return cloneElement(child, { section, key: `${props.id}-${order}` })\n })?.slice(start, end + 1)\n }, [renderRange$[0], renderRange$[1], children, root, props.id])\n\n /** 配对 pushNodesStructuralOnly:在 layout 阶段完成 Section 状态,避免 useMemo 内 setState 告警 */\n useLayoutEffect(() => {\n Children.forEach(children, (child: ReactElement<PropsWithChildren<_FlowSectionProps>>, order) => {\n if (Object.is(child, null)) {\n return\n }\n const sectionProps = child.props\n const sectionId = sectionProps.id || `section-${order}`\n root.findSection(sectionId)?.finalizePushNodesStateIfNeeded()\n })\n }, [children, root])\n\n const scrollTo = useMemoizedFn((scrollOffset = 0) => {\n scrollOffset = Math.max(0, scrollOffset)\n if (root.getState().scrollOffset === scrollOffset) return\n if (useScrollElementMode && effectiveScrollElement?.current) {\n const el = effectiveScrollElement.current as any\n const startOff = isWeapp ? effectiveStartOffsetRef.current : (startOffsetRef.current ?? 0)\n const scrollTarget = scrollOffset + startOff\n if (isH5) {\n el.scrollTo({ top: scrollTarget })\n } else if (isWeapp) {\n const scrollViewId = el.id || `_wf_${contentId}`\n if (!el.id) el.id = scrollViewId\n getScrollViewContextNode(`#${scrollViewId}`).then((node: any) => {\n node?.scrollTo?.({ top: scrollTarget, animated: true, duration: 300 })\n })\n }\n root.setStateBatch({ scrollOffset, isScrolling: true })\n root.sections.forEach((s) => s.getNodeRenderRange())\n return\n }\n getScrollViewContextNode(`#${root.id}`).then((node: any) => {\n node.scrollTo({\n animated: true,\n duration: 300,\n top: scrollOffset,\n })\n })\n })\n\n const resetScrolling = useMemoizedFn(() => {\n root.setStateIn('isScrolling', false)\n })\n\n const debouncedResetScrolling = debounce(resetScrolling)\n\n useEffect(() => {\n debouncedResetScrolling()\n }, [isScrolling$])\n\n /**\n * 处理滚动阈值\n * root 需入参:autoFind 从 pending→found 时 root 会重建,必须对新 root 重新订阅\n */\n useEffect(() => {\n const disposers = [\n root.sub(\n RootEvents.ReachUpperThreshold,\n debounce(() => {\n onScrollToUpper?.(refEventOrig.current!)\n })\n ),\n root.sub(\n RootEvents.ReachLowerThreshold,\n debounce(() => {\n onScrollToLower?.(refEventOrig.current!)\n })\n ),\n ]\n return () => {\n disposers.forEach((disposer) => {\n disposer()\n })\n }\n }, [root, onScrollToUpper, onScrollToLower])\n\n /**\n * 处理 scrollIntoView\n * 竞态:快速切换目标时,取消前一次滚动,避免后发先至\n */\n useEffect(() => {\n let cancelled = false\n handleScrollIntoView()\n async function handleScrollIntoView() {\n if (!scrollIntoView) return\n const targetNode = root.findNode(scrollIntoView)\n if (!targetNode) {\n nextTick(() => { if (!cancelled) onScrollIntoViewComplete?.() })\n return\n }\n const targetSection = targetNode.section\n const doScroll = () => {\n if (cancelled) return\n scrollTo(targetNode.getState().scrollTop)\n if (cancelled) return\n nextTick(() => { if (!cancelled) onScrollIntoViewComplete?.() })\n }\n if (!targetSection.getState().layouted) {\n const order = targetSection.order\n root.setStateIn('renderRange', [\n Math.min(renderRange$[0], order),\n Math.max(renderRange$[1], order),\n ])\n nextTick(async () => {\n await targetNode.section.layoutedSignal.promise\n if (cancelled) return\n doScroll()\n })\n return\n }\n await targetSection.layoutedSignal.promise\n if (cancelled) return\n doScroll()\n }\n return () => { cancelled = true }\n }, [scrollIntoView, renderRange$[0], renderRange$[1], onScrollIntoViewComplete])\n\n // scrollElement 模式下监听外部滚动,更新 root.scrollOffset;effectiveStartOffset 变化时重新同步;内嵌时 scrollRef 可能尚未就绪,需重试\n useEffect(() => {\n if (!useScrollElementMode || !effectiveScrollElement) return\n\n let cancelled = false\n let teardown: (() => void) | null = null\n const maxRetries = 20\n\n const tryAttach = (retryCount = 0) => {\n if (cancelled) return\n const target = effectiveScrollElement.current as any\n if (!target) {\n if (retryCount < maxRetries) {\n setTimeout(() => tryAttach(retryCount + 1), 50)\n }\n return\n }\n\n const getStartOffset = () => (isWeapp ? effectiveStartOffsetRef.current : (startOffsetRef.current ?? 0))\n\n const handler = (e?: any) => {\n const scrollTop = isWeapp\n ? (e?.target?.scrollTop ?? e?.mpEvent?.detail?.scrollTop ?? 0)\n : target.scrollTop\n const offset = scrollTop - getStartOffset()\n const effectiveOffset = Math.max(0, offset)\n const prevOffset = root.getState().scrollOffset\n const scrollDirection: ScrollDirection = prevOffset < effectiveOffset ? 'forward' : 'backward'\n\n nodeCacheCtlRef.current?.onScrollSample(effectiveOffset)\n root.sections.forEach((section) => section.getNodeRenderRange())\n root.setStateBatch({\n scrollDirection,\n scrollOffset: effectiveOffset,\n isScrolling: true,\n })\n }\n\n if (isWeapp) {\n if (!target.id) target.id = `_wf_${contentId}`\n const scrollViewId = target.id\n const instance = Taro.getCurrentInstance()\n const query = instance?.page\n ? Taro.createSelectorQuery().in(instance.page as any)\n : Taro.createSelectorQuery()\n query.select(`#${scrollViewId}`).scrollOffset().exec((res) => {\n if (cancelled) return\n const info = res?.[0]\n if (info) {\n const scrollTopVal = info.scrollTop ?? 0\n const initialOffset = Math.max(0, scrollTopVal - getStartOffset())\n root.setStateBatch({ scrollOffset: initialOffset, isScrolling: true })\n root.sections.forEach((s) => s.getNodeRenderRange())\n }\n })\n } else {\n const initialOffset = Math.max(0, target.scrollTop - getStartOffset())\n root.setStateBatch({ scrollOffset: initialOffset, isScrolling: true })\n root.sections.forEach((s) => s.getNodeRenderRange())\n }\n\n target.addEventListener('scroll', handler, isWeapp ? undefined : { passive: true })\n teardown = () => target.removeEventListener('scroll', handler)\n }\n\n tryAttach()\n return () => {\n cancelled = true\n teardown?.()\n }\n }, [useScrollElementMode, effectiveScrollElement, root, effectiveStartOffset, contentId])\n\n // scrollHeight 变化时回调(props 优先,其次从 Context),便于 List 动高联动;防抖 150ms 上报\n const reportHeight = onScrollHeightChange ?? scrollElementCtx?.reportNestedHeightChange\n useEffect(() => {\n if (!reportHeight || scrollHeight$ <= 0) return\n const timer = setTimeout(() => {\n if (Math.abs(lastReportedHeightRef.current - scrollHeight$) < 1) return\n lastReportedHeightRef.current = scrollHeight$\n reportHeight(scrollHeight$)\n }, 150)\n return () => clearTimeout(timer)\n }, [scrollHeight$, reportHeight])\n\n // scrollElement 模式下监听容器尺寸:H5 用 ResizeObserver,小程序用 createSelectorQuery 轮询\n useEffect(() => {\n if (!useScrollElementMode || !effectiveScrollElement) return\n const el = effectiveScrollElement.current as any\n if (!el) return\n\n if (isWeapp) {\n if (!el.id) el.id = `_wf_${contentId}`\n const scrollViewId = el.id\n const measure = () => {\n const instance = Taro.getCurrentInstance()\n const query = instance?.page\n ? Taro.createSelectorQuery().in(instance.page as any)\n : Taro.createSelectorQuery()\n query.select(`#${scrollViewId}`).boundingClientRect().exec((res) => {\n const rect = res?.[0]\n if (rect && rect.height > 0 && rect.width > 0) {\n const height = containerHeightRef.current ?? rect.height\n root.setStateIn('containerSize', { width: rect.width, height })\n }\n })\n }\n measure()\n const interval = setInterval(measure, 150)\n return () => clearInterval(interval)\n }\n\n if (typeof ResizeObserver === 'undefined') return\n const update = () => {\n const height = containerHeightRef.current ?? el.clientHeight\n const width = el.clientWidth\n if (height > 0 && width > 0) {\n root.setStateIn('containerSize', { width, height })\n }\n }\n update()\n const ro = new ResizeObserver(update)\n ro.observe(el)\n return () => ro.disconnect()\n }, [useScrollElementMode, effectiveScrollElement, root, effectiveContainerHeight, contentId])\n\n // scrollElement 模式下只渲染内容 View(不渲染 ScrollView);内容高度须为 scrollHeight 以支持父级滚动;needAutoFind 且 pending 时 probe 渲染以便查找父容器\n const renderView =\n useScrollElementMode || (!!needAutoFind && autoFindStatus === 'pending')\n if (renderView) {\n return createElement(\n View,\n {\n ref: setContainerRef as any,\n id: root.id,\n style: {\n ...style,\n width: '100%',\n position: 'relative',\n height: scrollHeight$,\n pointerEvents: isScrolling$ ? 'none' : 'auto',\n },\n className,\n },\n sections\n )\n }\n\n return createElement(\n ScrollView,\n {\n id: root.id,\n style: {\n WebkitOverflowScrolling: 'touch',\n overflow: 'auto',\n ...style,\n },\n className,\n scrollY: true,\n onScroll: handleScroll,\n ...rest,\n },\n createElement(\n View,\n {\n ref: setContainerRef as any,\n id: 'waterflow-root',\n style: {\n width: '100%',\n position: 'relative',\n height: scrollHeight$,\n pointerEvents: isScrolling$ ? 'none' : 'auto',\n },\n },\n sections\n )\n )\n}\n\nexport const WaterFlow = forwardRef<HTMLElement, PropsWithChildren<WaterFlowProps>>(InnerWaterFlow)\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tarojs/components-advanced",
|
|
3
|
-
"version": "4.1.12-beta.
|
|
3
|
+
"version": "4.1.12-beta.17",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "O2Team",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,20 +20,20 @@
|
|
|
20
20
|
"csstype": "^3.1.1",
|
|
21
21
|
"memoize-one": "^6.0.0",
|
|
22
22
|
"tslib": "^2.6.2",
|
|
23
|
-
"@tarojs/components": "4.1.12-beta.
|
|
24
|
-
"@tarojs/components-react": "4.1.12-beta.
|
|
23
|
+
"@tarojs/components": "4.1.12-beta.17",
|
|
24
|
+
"@tarojs/components-react": "4.1.12-beta.17"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"vue": "3.2.47",
|
|
28
|
-
"@tarojs/runtime": "4.1.12-beta.
|
|
29
|
-
"@tarojs/shared": "4.1.12-beta.
|
|
30
|
-
"@tarojs/taro": "4.1.12-beta.
|
|
28
|
+
"@tarojs/runtime": "4.1.12-beta.17",
|
|
29
|
+
"@tarojs/shared": "4.1.12-beta.17",
|
|
30
|
+
"@tarojs/taro": "4.1.12-beta.17"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"react": ">=18",
|
|
34
|
-
"@tarojs/shared": "~4.1.12-beta.
|
|
35
|
-
"@tarojs/
|
|
36
|
-
"@tarojs/
|
|
34
|
+
"@tarojs/shared": "~4.1.12-beta.17",
|
|
35
|
+
"@tarojs/runtime": "~4.1.12-beta.17",
|
|
36
|
+
"@tarojs/taro": "~4.1.12-beta.17"
|
|
37
37
|
},
|
|
38
38
|
"peerDependenciesMeta": {
|
|
39
39
|
"react": {
|