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);
+ });
+ });
+});