Skip to content

Commit 2f12958

Browse files
committed
Add scroll to top / bottom
1 parent 8c84ce2 commit 2f12958

File tree

1 file changed

+37
-9
lines changed

1 file changed

+37
-9
lines changed

src/index.js

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const VirtualList = Vue.component(NAME, {
4949
uniqueIds: this.getUniqueIdFromDataSources()
5050
}, this.onRangeChanged)
5151

52-
// also need sync initial range first
52+
// sync initial range
5353
this.range = this.virtual.getRange()
5454

5555
// listen item size changing
@@ -87,8 +87,16 @@ const VirtualList = Vue.component(NAME, {
8787

8888
// set current scroll position to a expectant index
8989
scrollToIndex (index) {
90-
const offset = this.virtual.getOffset(index)
91-
this.scrollToOffset(offset)
90+
// scroll to top
91+
if (index === 0) {
92+
this.scrollToOffset(0)
93+
} else if (index >= this.dataSources.length - 1) {
94+
// scroll to bottom
95+
this.scrollToOffset(this.getScrollSize())
96+
} else {
97+
const offset = this.virtual.getOffset(index)
98+
this.scrollToOffset(offset)
99+
}
92100
},
93101

94102
// ----------- public method end -----------
@@ -97,6 +105,26 @@ const VirtualList = Vue.component(NAME, {
97105
return this.dataSources.map((dataSource) => dataSource[this.dataKey])
98106
},
99107

108+
// get client viewport size (width or height)
109+
getClientSize () {
110+
const { root } = this.$refs
111+
if (root) {
112+
return root[this.isHorizontal ? 'clientWidth' : 'clientHeight']
113+
} else {
114+
return 0
115+
}
116+
},
117+
118+
// get all scroll size (width or height)
119+
getScrollSize () {
120+
const { root } = this.$refs
121+
if (root) {
122+
return root[this.isHorizontal ? 'scrollWidth' : 'scrollHeight']
123+
} else {
124+
return 0
125+
}
126+
},
127+
100128
// event called when each item mounted or size changed
101129
onItemResized (id, size) {
102130
this.virtual.saveSize(id, size)
@@ -127,24 +155,24 @@ const VirtualList = Vue.component(NAME, {
127155
}
128156

129157
const offset = root[this.directionKey]
130-
const offsetShape = root[this.isHorizontal ? 'clientWidth' : 'clientHeight']
131-
const scrollShape = root[this.isHorizontal ? 'scrollWidth' : 'scrollHeight']
158+
const clientSize = this.getClientSize()
159+
const scrollSize = this.getScrollSize()
132160

133161
// iOS scroll-spring-back behavior will make direction mistake
134-
if (offset + offsetShape > scrollShape) {
162+
if (offset + clientSize > scrollSize) {
135163
return
136164
}
137165

138166
this.virtual.handleScroll(offset)
139-
this.emitEvent(offset, offsetShape, scrollShape, evt)
167+
this.emitEvent(offset, clientSize, scrollSize, evt)
140168
},
141169

142170
// emit event in special position
143-
emitEvent (offset, offsetShape, scrollShape, evt) {
171+
emitEvent (offset, clientSize, scrollSize, evt) {
144172
const range = this.virtual.getRange()
145173
if (this.virtual.isFront() && !!this.dataSources.length && offset - this.topThreshold <= 0) {
146174
this.$emit('totop', evt, range)
147-
} else if (this.virtual.isBehind() && offset + offsetShape + this.bottomThreshold >= scrollShape) {
175+
} else if (this.virtual.isBehind() && offset + clientSize + this.bottomThreshold >= scrollSize) {
148176
this.$emit('tobottom', evt, range)
149177
} else {
150178
this.$emit('scroll', evt, range)

0 commit comments

Comments
 (0)