Skip to content

explainers-by-googlers/promisify-scroll

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Explainer: Programmatic Scroll Promise

This proposal is an early design sketch by Blink Interactions Team to describe the problem below and solicit feedback on the proposed solution. It has not been approved to ship in Chrome.

Proponents

  • Blink Interactions Team

Participate

Table of Contents

Introduction

Web developers currently have no way to know when a programmatic smooth-scroll has completed. A solution to the problem that has already been resolved in the CSS WG: make the programmatic scroll methods return Promise objects that get resolved on scroll completion. This explainer provides details of the solution, for spec updates and implementation.

Goals

We have six scroll methods available through both Element and Window interfaces. These methods return immediately with the value undefined, which was fine during the early days of the web when scroll was assumed to be instant. This behavior no longer seems adequate from a web developer's perspective today: there is widespread support for smooth-scroll (see browser_compatibility for the CSS property), and it is not easy for the developers to determine when a particular call for a smooth-scroll has completed.

This explainer elaborates how to make those methods return Promise objects to solve this problem, as per the CSS WG resolution in w3c/csswg-drafts#1562.

Non-goals

  • Alternatives to returning Promise objects.
  • Details of smooth-scroll behavior or chaining of nested scrollers.

Use cases

Disabling UI during programmatic smooth-scroll

Imagine a custom scroller that relies on programmatic scroll and that its buttons get disabled while a smooth-scroll is ongoing.

Solution

The CSS WG discussion at w3c/csswg-drafts#1562 resolved that the scroll methods in Element and Window would return Promise objects (instead of undefined). For that we would modifiy the IDL for Element as follows:

partial interface Element {
  Promise<undefined> scrollIntoView(optional (boolean or ScrollIntoViewOptions) arg = {});
  Promise<undefined> scroll(optional ScrollToOptions options = {});
  Promise<undefined> scroll(unrestricted double x, unrestricted double y);
  Promise<undefined> scrollTo(optional ScrollToOptions options = {});
  Promise<undefined> scrollTo(unrestricted double x, unrestricted double y);
  Promise<undefined> scrollBy(optional ScrollToOptions options = {});
  Promise<undefined> scrollBy(unrestricted double x, unrestricted double y);
}

We would need a very similar change in the IDL for Window too.

This change would allow developers do things very easily at the completion of a scroll, like this:

  element.scrollTo(0, 100).then(() => {
     // Do something at the end of the scroll.
  });

or this:

  await element.scrollTo(0, 100);
  // Do something at the end of the scroll.

How this solution would solve the use cases

For the use-case above, disabling a button during programmatic smooth-scroll would be as simple as:

  button.onclick = async () => {
    button.classList.add("dimmed");
    await container.scrollTo(0, 0);
    button.classList.remove("dimmed");
  }

Here is a demo (the button dims only when the feature is enabled).

Promise rejection

To maintain the backward compatibility for the scroll methods, we would avoid rejecting the returned Promises (as much as possible). This is because unhandled Promise rejections are treated as exceptions, which could fail any JS callers that assume that those methods succeed unconditionally.

To be precise about the Promise rejection behavior, if a scroll is not needed because the scroll position is already correct, the returned Promise would be resolved immediately. If an ongoing programmatic scroll is interrupted by either a user gesture or by another invocation of a programmatic scroll, at the moment of the interruption the (first) scroll would be considered complete and the Promise would be resolved.

About

Make Element/Window scroll methods return Promises

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published