diff --git a/core/src/components/infinite-scroll/infinite-scroll.tsx b/core/src/components/infinite-scroll/infinite-scroll.tsx index 190fab5863..25de713eeb 100644 --- a/core/src/components/infinite-scroll/infinite-scroll.tsx +++ b/core/src/components/infinite-scroll/infinite-scroll.tsx @@ -12,6 +12,14 @@ export class InfiniteScroll implements ComponentInterface { private thrPx = 0; private thrPc = 0; private scrollEl?: HTMLElement; + + /** + * didFire exists so that ionInfinite + * does not fire multiple times if + * users continue to scroll after + * scrolling into the infinite + * scroll threshold. + */ private didFire = false; private isBusy = false; @@ -127,8 +135,6 @@ export class InfiniteScroll implements ComponentInterface { this.ionInfinite.emit(); return 3; } - } else { - this.didFire = false; } return 4; @@ -190,10 +196,13 @@ export class InfiniteScroll implements ComponentInterface { writeTask(() => { scrollEl.scrollTop = newScrollTop; this.isBusy = false; + this.didFire = false; }); }); }); }); + } else { + this.didFire = false; } } diff --git a/core/src/components/infinite-scroll/test/small-dom-update/index.html b/core/src/components/infinite-scroll/test/small-dom-update/index.html new file mode 100644 index 0000000000..16a67ae763 --- /dev/null +++ b/core/src/components/infinite-scroll/test/small-dom-update/index.html @@ -0,0 +1,63 @@ + + + + + Infinite Scroll - Small DOM Update + + + + + + + + + + + + +
+ + + + + +
+
+ + + + diff --git a/core/src/components/infinite-scroll/test/small-dom-update/infinite-scroll.e2e.ts b/core/src/components/infinite-scroll/test/small-dom-update/infinite-scroll.e2e.ts new file mode 100644 index 0000000000..c76140657d --- /dev/null +++ b/core/src/components/infinite-scroll/test/small-dom-update/infinite-scroll.e2e.ts @@ -0,0 +1,34 @@ +import { expect } from '@playwright/test'; +import { configs, test } from '@utils/test/playwright'; + +configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => { + test.describe(title('infinite-scroll: appending small amounts to dom'), () => { + test('should load more after remaining in threshold', async ({ page }) => { + await page.goto('/src/components/infinite-scroll/test/small-dom-update', config); + + const ionInfiniteComplete = await page.spyOnEvent('ionInfiniteComplete'); + const content = page.locator('ion-content'); + const items = page.locator('#list .item'); + expect(await items.count()).toBe(30); + + await content.evaluate((el: HTMLIonContentElement) => el.scrollToBottom(0)); + await ionInfiniteComplete.next(); + + /** + * Even after appending we'll still be within + * the infinite scroll's threshold + */ + expect(await items.count()).toBe(33); + + await content.evaluate((el: HTMLIonContentElement) => el.scrollToBottom(0)); + await ionInfiniteComplete.next(); + + /** + * Scrolling down again without leaving + * the threshold should still trigger + * infinite scroll again. + */ + expect(await items.count()).toBe(36); + }); + }); +});