v149 · JavaScript · Web APIs

Programmatic scroll promise

element.scrollTo(), scrollBy(), and scrollIntoView() now return a Promise that resolves when the scroll animation completes — or rejects if it's interrupted.

concepts

  1. Scroll Monitor

    A live log showing scrollTo() promises resolving and rejecting. Interrupt scrolls mid-flight by clicking "scroll elsewhere" to see the interrupted status reported in the promise.

  2. Animation Sequencer

    Chain scroll animations using await scrollTo(…). Each section scrolls into view before the next one starts — guaranteed by the promise, not a fragile setTimeout.

  3. Guided Tour

    A sequential 5-stop guided tour where each scroll awaits completion before highlighting the next section. User interruptions trigger Promise rejection, cleanly aborting the sequence. Adjustable pace and easing.

  4. Concurrent Scroll Race

    Click multiple destination buttons rapidly to trigger overlapping scrollTo() calls. A live scoreboard shows which scroll won ({ interrupted: false }) and which were knocked out ({ interrupted: true }). Hit "Auto-race" to see the race in slow motion.

  5. Scroll Sequencing with Recovery

    A chapter-by-chapter reader tour that catches { interrupted: true } and shows a recovery bar offering to resume or cancel. Demonstrates the retry-on-interrupt pattern for guided UX flows.

  6. Scroll Progress Tracker

    A five-chapter document with a progress bar that only advances when each scrollTo() promise resolves with { interrupted: false }. Interrupt at any time — the bar pauses and a Resume button appears. Speed control (fast/normal/slow) and a chapter-strip let you jump or restart at any point. Shows how the promise makes real reading-progress tracking trivial.

why it shipped

Before Chrome 149, JavaScript had no way to know when a smooth scroll triggered by scrollTo() or scrollIntoView() had finished. Developers used setTimeout heuristics or polled scrollTop in a loop — both brittle and inaccurate, especially if the user interrupted the scroll. Now scrollTo({ behavior: 'smooth' }) returns a Promise<ScrollPromiseResult> that resolves with { interrupted: false } on clean completion or { interrupted: true } if the scroll was cancelled. This unlocks properly sequenced scroll-based UX without timers.

references