Skip to content

Commit 2d0f449

Browse files
bkboothclaude
andcommitted
fix(pixel): clean up scroll depth implementation (SDK-136)
- Rename above_fold → aboveFold for consistency with all other autocapture event properties (camelCase convention) - Remove dead aboveFold parameter from checkAndFire — it was always false after the dwell timer got its own inline path - Remove deprecated window.pageYOffset fallback — all supported browsers (Chrome 80+) have window.scrollY Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent cf0872f commit 2d0f449

3 files changed

Lines changed: 11 additions & 13 deletions

File tree

packages/audience/pixel/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ All events fire automatically with no instrumentation required.
8585
| `session_end` | Page unload (`visibilitychange` / `pagehide`) | `sessionId`, `duration` (seconds) |
8686
| `form_submitted` | HTML form submission | `formAction`, `formId`, `formName`, `fieldNames`. `emailHash` at `full` consent only. |
8787
| `link_clicked` | Outbound link click (external domains only) | `linkUrl`, `linkText`, `elementId`, `outbound: true` |
88-
| `scroll_depth` | Scroll milestone reached (25%, 50%, 75%, 90%, 100%) | `depth` (integer). On above-the-fold pages (no scroll possible), fires `depth: 100` with `above_fold: true` after a 2-second dwell. |
88+
| `scroll_depth` | Scroll milestone reached (25%, 50%, 75%, 90%, 100%) | `depth` (integer). On above-the-fold pages (no scroll possible), fires `depth: 100` with `aboveFold: true` after a 2-second dwell. |
8989

9090
### Disabling specific auto-capture
9191

packages/audience/pixel/src/autocapture.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -680,15 +680,15 @@ describe('autocapture', () => {
680680
expect(enqueue).toHaveBeenCalledTimes(5);
681681
});
682682

683-
it('does not include above_fold property on scrollable pages', () => {
683+
it('does not include aboveFold property on scrollable pages', () => {
684684
setup({ scroll: true });
685685

686686
(window as Record<string, unknown>).scrollY = 375;
687687
window.dispatchEvent(new Event('scroll'));
688688
flushRAF();
689689

690690
expect(enqueue.mock.calls[0][1]).toEqual({ depth: 25 });
691-
expect(enqueue.mock.calls[0][1]).not.toHaveProperty('above_fold');
691+
expect(enqueue.mock.calls[0][1]).not.toHaveProperty('aboveFold');
692692
});
693693

694694
it('does not fire at consent none', () => {
@@ -740,7 +740,7 @@ describe('autocapture', () => {
740740
jest.useRealTimers();
741741
});
742742

743-
it('fires scroll_depth 100 with above_fold after dwell time', () => {
743+
it('fires scroll_depth 100 with aboveFold after dwell time', () => {
744744
setup({ scroll: true });
745745

746746
// Should NOT fire immediately
@@ -751,7 +751,7 @@ describe('autocapture', () => {
751751

752752
expect(enqueue).toHaveBeenCalledWith('scroll_depth', {
753753
depth: 100,
754-
above_fold: true,
754+
aboveFold: true,
755755
});
756756
expect(enqueue).toHaveBeenCalledTimes(1);
757757
});

packages/audience/pixel/src/autocapture.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ function getScrollPercent(): number {
7171
const { scrollHeight, clientHeight } = document.documentElement;
7272
if (scrollHeight <= clientHeight) return 100;
7373
const scrollable = scrollHeight - clientHeight;
74-
return Math.min(100, Math.round(((window.scrollY || window.pageYOffset) / scrollable) * 100));
74+
return Math.min(100, Math.round((window.scrollY / scrollable) * 100));
7575
}
7676

7777
/**
@@ -91,17 +91,15 @@ function setupScrollTracking(
9191
let rafId = 0;
9292
let dwellTimer: ReturnType<typeof setTimeout> | null = null;
9393

94-
const checkAndFire = (aboveFold: boolean): void => {
94+
const checkAndFire = (): void => {
9595
if (!canTrack(getConsent())) return;
9696

9797
const pct = getScrollPercent();
9898
for (let i = 0; i < SCROLL_MILESTONES.length; i++) {
9999
const milestone = SCROLL_MILESTONES[i];
100100
if (pct >= milestone && !fired.has(milestone)) {
101101
fired.add(milestone);
102-
const properties: Record<string, unknown> = { depth: milestone };
103-
if (aboveFold) properties.above_fold = true;
104-
enqueue('scroll_depth', properties);
102+
enqueue('scroll_depth', { depth: milestone });
105103
}
106104
}
107105
};
@@ -117,12 +115,12 @@ function setupScrollTracking(
117115
if (!canTrack(getConsent())) return;
118116
if (!fired.has(100)) {
119117
fired.add(100);
120-
enqueue('scroll_depth', { depth: 100, above_fold: true });
118+
enqueue('scroll_depth', { depth: 100, aboveFold: true });
121119
}
122120
}, ABOVE_FOLD_DWELL_MS);
123121
} else {
124122
// Check initial scroll position (e.g. anchor links, restored scroll).
125-
checkAndFire(false);
123+
checkAndFire();
126124
}
127125

128126
// Scroll listener (handles both scrollable pages and pages that become
@@ -131,7 +129,7 @@ function setupScrollTracking(
131129
if (rafId) return; // Already scheduled
132130
rafId = requestAnimationFrame(() => {
133131
rafId = 0;
134-
checkAndFire(false);
132+
checkAndFire();
135133
});
136134
};
137135

0 commit comments

Comments
 (0)