mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-22 05:21:52 +08:00
refactor(scroll): merge into ion-content
This commit is contained in:
@ -8,7 +8,7 @@ export class InfiniteScroll {
|
||||
|
||||
private thrPx = 0;
|
||||
private thrPc = 0;
|
||||
private scrollEl?: HTMLIonScrollElement;
|
||||
private scrollEl?: HTMLElement;
|
||||
private didFire = false;
|
||||
private isBusy = false;
|
||||
|
||||
@ -81,9 +81,13 @@ export class InfiniteScroll {
|
||||
}
|
||||
this.thresholdChanged(this.threshold);
|
||||
this.enableScrollEvents(!this.disabled);
|
||||
if (this.position === 'top') {
|
||||
this.queue.write(() => this.scrollEl && this.scrollEl.scrollToBottom(0));
|
||||
}
|
||||
// if (this.position === 'top') {
|
||||
// this.queue.write(() => {
|
||||
// if (this.scrollEl) {
|
||||
// this.scrollEl.scrollTop = this.scrollEl.scrollHeight - this.scrollEl.clientHeight;
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
componentDidUnload() {
|
||||
@ -143,45 +147,45 @@ export class InfiniteScroll {
|
||||
}
|
||||
this.isLoading = false;
|
||||
|
||||
if (this.position === 'top') {
|
||||
/**
|
||||
* New content is being added at the top, but the scrollTop position stays the same,
|
||||
* which causes a scroll jump visually. This algorithm makes sure to prevent this.
|
||||
* (Frame 1)
|
||||
* - complete() is called, but the UI hasn't had time to update yet.
|
||||
* - Save the current content dimensions.
|
||||
* - Wait for the next frame using _dom.read, so the UI will be updated.
|
||||
* (Frame 2)
|
||||
* - Read the new content dimensions.
|
||||
* - Calculate the height difference and the new scroll position.
|
||||
* - Delay the scroll position change until other possible dom reads are done using _dom.write to be performant.
|
||||
* (Still frame 2, if I'm correct)
|
||||
* - Change the scroll position (= visually maintain the scroll position).
|
||||
* - Change the state to re-enable the InfiniteScroll.
|
||||
* - This should be after changing the scroll position, or it could
|
||||
* cause the InfiniteScroll to be triggered again immediately.
|
||||
* (Frame 3)
|
||||
* Done.
|
||||
*/
|
||||
this.isBusy = true;
|
||||
// ******** DOM READ ****************
|
||||
// Save the current content dimensions before the UI updates
|
||||
const prev = scrollEl.scrollHeight - scrollEl.scrollTop;
|
||||
// if (this.position === 'top') {
|
||||
// /**
|
||||
// * New content is being added at the top, but the scrollTop position stays the same,
|
||||
// * which causes a scroll jump visually. This algorithm makes sure to prevent this.
|
||||
// * (Frame 1)
|
||||
// * - complete() is called, but the UI hasn't had time to update yet.
|
||||
// * - Save the current content dimensions.
|
||||
// * - Wait for the next frame using _dom.read, so the UI will be updated.
|
||||
// * (Frame 2)
|
||||
// * - Read the new content dimensions.
|
||||
// * - Calculate the height difference and the new scroll position.
|
||||
// * - Delay the scroll position change until other possible dom reads are done using _dom.write to be performant.
|
||||
// * (Still frame 2, if I'm correct)
|
||||
// * - Change the scroll position (= visually maintain the scroll position).
|
||||
// * - Change the state to re-enable the InfiniteScroll.
|
||||
// * - This should be after changing the scroll position, or it could
|
||||
// * cause the InfiniteScroll to be triggered again immediately.
|
||||
// * (Frame 3)
|
||||
// * Done.
|
||||
// */
|
||||
// this.isBusy = true;
|
||||
// // ******** DOM READ ****************
|
||||
// // Save the current content dimensions before the UI updates
|
||||
// const prev = scrollEl.scrollHeight - scrollEl.scrollTop;
|
||||
|
||||
// ******** DOM READ ****************
|
||||
this.queue.read(() => {
|
||||
// UI has updated, save the new content dimensions
|
||||
const scrollHeight = scrollEl.scrollHeight;
|
||||
// New content was added on top, so the scroll position should be changed immediately to prevent it from jumping around
|
||||
const newScrollTop = scrollHeight - prev;
|
||||
// // ******** DOM READ ****************
|
||||
// this.queue.read(() => {
|
||||
// // UI has updated, save the new content dimensions
|
||||
// const scrollHeight = scrollEl.scrollHeight;
|
||||
// // New content was added on top, so the scroll position should be changed immediately to prevent it from jumping around
|
||||
// const newScrollTop = scrollHeight - prev;
|
||||
|
||||
// ******** DOM WRITE ****************
|
||||
this.queue.write(() => {
|
||||
scrollEl.scrollTop = newScrollTop;
|
||||
this.isBusy = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
// // ******** DOM WRITE ****************
|
||||
// this.queue.write(() => {
|
||||
// scrollEl.scrollTop = newScrollTop;
|
||||
// this.isBusy = false;
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,10 +38,6 @@
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
let items = [];
|
||||
for (var i = 0; i < 30; i++) {
|
||||
items.push(i + 1);
|
||||
}
|
||||
const list = document.getElementById('list');
|
||||
const infiniteScroll = document.getElementById('infinite-scroll');
|
||||
|
||||
@ -51,35 +47,30 @@
|
||||
|
||||
infiniteScroll.addEventListener('ionInfinite', async function () {
|
||||
console.log('Loading data...');
|
||||
const data = await getAsyncData();
|
||||
items = items.concat(data);
|
||||
await wait(500);
|
||||
infiniteScroll.complete();
|
||||
render();
|
||||
appendItems();
|
||||
|
||||
console.log('Done');
|
||||
});
|
||||
|
||||
function render() {
|
||||
let html = '';
|
||||
for (let item of items) {
|
||||
html += `<ion-item>${item}</ion-item>`;
|
||||
function appendItems() {
|
||||
for (var i = 0; i < 30; i++) {
|
||||
const el = document.createElement('ion-item');
|
||||
el.textContent = `${1 + i}`;
|
||||
list.appendChild(el);
|
||||
}
|
||||
list.innerHTML = html;
|
||||
}
|
||||
|
||||
function getAsyncData() {
|
||||
// async return mock data
|
||||
function wait(time) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
let data = [];
|
||||
for (var i = 0; i < 30; i++) {
|
||||
data.push(i);
|
||||
}
|
||||
|
||||
resolve(data);
|
||||
}, 500);
|
||||
resolve();
|
||||
}, time);
|
||||
});
|
||||
}
|
||||
render();
|
||||
|
||||
appendItems();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
Reference in New Issue
Block a user