Skip to content

Commit a85182c

Browse files
committed
Use estimate paddingBottom.
1 parent 1548599 commit a85182c

File tree

1 file changed

+55
-22
lines changed

1 file changed

+55
-22
lines changed

index.js

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,23 @@
5656
var bench = this.bench || this.remain
5757
var keeps = this.remain + bench
5858
var slots = this.$slots.default
59-
var total = slots && slots.length || 0
59+
var total = (slots && slots.length) || 0
6060

6161
this.delta = {
62-
start: start, // start index.
63-
end: start + keeps, // end index.
64-
total: total, // all items count.
65-
keeps: keeps, // nums keeping in real dom.
66-
bench: bench, // nums scroll pass should force update.
67-
offset: 0, // cache scrollTop offset.
68-
direct: 'd', // cache scroll direction.
69-
height: height, // container wrapper viewport height.
70-
fireTime: 0, // cache last event fire time avoid compact.
71-
paddingTop: 0, // container wrapper real padding-top.
72-
paddingBottom: 0, // container wrapper real padding-bottom.
73-
variableData: {} // cache variable index height and padding offset.
62+
start: start, // start index.
63+
end: start + keeps, // end index.
64+
total: total, // all items count.
65+
keeps: keeps, // nums keeping in real dom.
66+
bench: bench, // nums scroll pass should force update.
67+
offset: 0, // cache scrollTop offset.
68+
direct: 'd', // cache scroll direction.
69+
height: height, // container wrapper viewport height.
70+
fireTime: 0, // cache last event fire time avoid compact.
71+
paddingTop: 0, // container wrapper real padding-top.
72+
paddingBottom: 0, // container wrapper real padding-bottom.
73+
varCache: {}, // cache variable index height and padding offset.
74+
averageSize: 0, // average/estimate item height before variable be calculated.
75+
lastCalcIndex: 0 // last calculated variable height/offset index, always increase.
7476
}
7577
},
7678

@@ -154,22 +156,26 @@
154156

155157
delta.end = end
156158
delta.start = start
157-
158-
// call component to update shown items.
159159
this.$forceUpdate()
160160
},
161161

162162
// return the scroll passed items count in variable height.
163163
getVarOvers: function (offset) {
164+
var delta = this.delta
164165
var low = 0
165-
var high = this.delta.total
166-
167166
var middle = 0
168167
var middleOffset = 0
168+
var high = delta.total
169+
169170
while (low <= high) {
170171
middle = low + Math.floor((high - low) / 2)
171172
middleOffset = this.getVarOffset(middle)
172173

174+
// calculate the averageSize at first binary search.
175+
if (!delta.averageSize) {
176+
delta.averageSize = Math.floor(middleOffset / middle)
177+
}
178+
173179
if (middleOffset === offset) {
174180
return middle
175181
} else if (middleOffset < offset) {
@@ -184,18 +190,45 @@
184190

185191
// get the variable height index scroll offset.
186192
getVarOffset: function (index) {
187-
var i = index
193+
var delta = this.delta
194+
var cache = delta.varCache[index]
195+
196+
if (cache) {
197+
return cache.offset
198+
}
199+
188200
var offset = 0
189-
while (i--) {
190-
offset += this.getVarSize(i)
201+
for (var i = 0; i < index; i++) {
202+
var size = this.getVarSize(i)
203+
delta.varCache[i] = {
204+
size: size,
205+
offset: offset
206+
}
207+
offset += size
191208
}
192209

210+
delta.lastCalcIndex = Math.max(delta.lastCalcIndex, index)
211+
193212
return offset
194213
},
195214

196215
// return a variable size (height) from a given index.
197216
getVarSize: function (index) {
198-
return this.variable(index) || 0
217+
var cache = this.delta.varCache[index]
218+
return (cache && cache.size) || this.variable(index) || 0
219+
},
220+
221+
// return the paddingBottom when variable height base current zone.
222+
getVarPaddingBottom () {
223+
var delta = this.delta
224+
var rest = delta.total - delta.lastCalcIndex
225+
if (rest <= delta.keeps || delta.lastCalcIndex >= delta.total) {
226+
return this.getVarOffset(delta.total) - this.getVarOffset(delta.end)
227+
} else {
228+
// if unreached last zone or uncalculate real behind offset
229+
// continue return the estimate paddingBottom avoid max calculate.
230+
return (delta.total - delta.lastCalcIndex) * (delta.averageSize || this.size)
231+
}
199232
},
200233

201234
// avoid overflow range.
@@ -253,7 +286,7 @@
253286

254287
if (this.variable) {
255288
paddingTop = hasPadding ? this.getVarOffset(delta.start) : 0
256-
paddingBottom = hasPadding ? this.getVarOffset(delta.total) - this.getVarOffset(delta.end) : 0
289+
paddingBottom = hasPadding ? this.getVarPaddingBottom() : 0
257290
} else {
258291
paddingTop = this.size * (hasPadding ? delta.start : 0)
259292
paddingBottom = this.size * (hasPadding ? slots.length - delta.keeps : 0) - paddingTop

0 commit comments

Comments
 (0)