Skip to content

Conversation

@tyiuhc
Copy link
Collaborator

@tyiuhc tyiuhc commented Dec 18, 2025

Summary

Support scrolled_to page trigger, which fires when:

  1. percentage mode: user scrolls down the specified minimum percent of the page
  2. element mode: user scrolls down to an element (offset by optional offsetPx)

Checklist

  • Does your PR title have the correct title format?
  • Does your PR have a breaking change?: No

@macroscopeapp
Copy link

macroscopeapp bot commented Dec 18, 2025

Add 'scrolled_to' trigger and publish scroll events via SubscriptionManager.setupScrolledToPublisher in subscriptions.ts

Introduce scrolled_to message type and payload, add scroll percentage and element-offset evaluation, and update page object activation to react to scroll-based thresholds.

📍Where to Start

Start with SubscriptionManager.setupScrolledToPublisher in subscriptions.ts.


Macroscope summarized 4df1133.

wrapHistoryMethods();
};

private setupScrolledToPublisher = () => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setupScrolledToPublisher adds a new scroll listener every time initSubscriptions() runs, but never removes the old one. This can leak and double-fire in visual editor mode where initSubscriptions() is called repeatedly. Consider removing any previous listener before attaching a new one (or keep a single shared handler).

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

@promptless
Copy link

promptless bot commented Dec 18, 2025

📝 Documentation updates detected!

Updated existing suggestion: Document new page trigger types for Web Experiment

wrapHistoryMethods();
};

private setupScrolledToPublisher = () => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scrolled_to publishes on every scroll once a target is met, unlike element_visible which de-dupes after first fire. Consider tracking which percentages/elements have already fired and only publish when a new target is first reached to avoid repeatedly triggering applyVariants() during scrolling.

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

@tyiuhc tyiuhc requested a review from a team December 19, 2025 00:09
Comment on lines +424 to +426
for (const pages of Object.values(this.pageObjects)) {
for (const page of Object.values(pages)) {
if (page.trigger_type === 'scrolled_to') {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I see a repeated pattern for each trigger types. Consider refactoring.


this.globalScope.addEventListener(
'scroll',
() => handleScroll(minPercentage, elementTargets),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider throttling (e.g. requestAnimationFrame) since the scroll event can fire a lot. Each fires querySelector + getBoundingClientRect for every element target, forcing a reflow.

Comment on lines +470 to +475
const scrollPosition = this.globalScope.scrollY;

if (
scrollPosition + this.globalScope.innerHeight >=
elementPosition + scrollPosition + offsetPx
) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scrollPosition would be canceled out. Should remove this.

const elementAndOffset = new Set<string>();

// Check which elements are in range
for (const { selector, offsetPx } of elements) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: WDYT about using IntersectionObserver for scrolled to element trigger type?

const elementAndOffset = scrollPayload.elementAndOffset;

if (triggerValue.mode === 'percent') {
return currentScrollPercentage >= triggerValue.percentage;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The “scrolled to” condition should not be re-evaluated when the user scrolls back up. Once it’s exposed, it should remain active until the exit condition occurs—in this case, a URL change (the default exit condition).

Comment on lines +482 to +492
// Publish if minimum percentage threshold is met or any element is in range
const shouldPublish =
(minPercent !== undefined && scrollPercentage >= minPercent) ||
elementAndOffset.size > 0;

if (shouldPublish) {
this.messageBus.publish('scrolled_to', {
scrollPercentage,
elementAndOffset,
});
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that other trigger types evaluate in the subscription, I'd suggest moving this logic. Also you won't have to deal with this if you change the element scroll with IntersectionObserver.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants