Skip to content

Commit d273f3e

Browse files
authored
Merge pull request #14 from sveltejs/handle-row-height-changes
compensate for changed row heights
2 parents 3d2cb49 + 1283c48 commit d273f3e

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

src/VirtualList.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,19 @@
163163
start: newStart,
164164
end: newEnd
165165
});
166+
167+
if (newStart < start) {
168+
let d = 0;
169+
170+
for (let i = newStart; i < start; i += 1) {
171+
const expectedHeight = this.heightMap[i];
172+
const actualHeight = this.rows[i - newStart].offsetHeight;
173+
174+
d += actualHeight - expectedHeight;
175+
}
176+
177+
this.refs.viewport.scrollTo(0, this.refs.viewport.scrollTop + d);
178+
}
166179
}
167180
}
168181
};

test/src/index.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,5 +260,43 @@ test('updates when items change from an empty list', t => {
260260
list.destroy();
261261
});
262262

263+
test('handles unexpected height changes when scrolling up', async t => {
264+
const Row = svelte.create(`
265+
<div style="height: {rowHeight}px;">test</div>
266+
`);
267+
268+
const list = new VirtualList({
269+
target,
270+
data: {
271+
items: Array(20).fill().map(() => ({})),
272+
component: Row,
273+
height: '500px',
274+
rowHeight: 50
275+
}
276+
});
277+
278+
const { viewport } = list.refs;
279+
280+
await scroll(viewport, 500);
281+
assert.equal(viewport.scrollTop, 500);
282+
283+
list.set({ rowHeight: 100 });
284+
await scroll(viewport, 475);
285+
assert.equal(viewport.scrollTop, 525);
286+
287+
list.destroy();
288+
});
289+
290+
function scroll(element, y) {
291+
return new Promise(fulfil => {
292+
element.addEventListener('scroll', function handler() {
293+
element.removeEventListener('scroll', handler);
294+
fulfil();
295+
});
296+
297+
element.scrollTo(0, y);
298+
});
299+
}
300+
263301
// this allows us to close puppeteer once tests have completed
264302
window.done = done;

0 commit comments

Comments
 (0)