-
Notifications
You must be signed in to change notification settings - Fork 23.2k
Technical review: Document scroll promise return values #44515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c236fe8
6a06db7
428966a
77988ef
0fe1b65
96d6375
9a8c56c
8c18be1
2c43e0d
ade4ed9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,9 +8,7 @@ browser-compat: api.Element.scroll | |
|
|
||
| {{APIRef("CSSOM view API")}} | ||
|
|
||
| The **`scroll()`** method of the {{domxref("Element")}} | ||
| interface scrolls the element to a particular set of coordinates inside a given | ||
| element. | ||
| The **`scroll()`** method of the {{domxref("Element")}} interface scrolls to a particular set of coordinates inside a given element. | ||
|
|
||
| ## Syntax | ||
|
|
||
|
|
@@ -22,29 +20,34 @@ scroll(options) | |
| ### Parameters | ||
|
|
||
| - `xCoord` | ||
| - : The pixel along the horizontal axis of the element that you want displayed in the | ||
| upper left. | ||
| - : The pixel along the horizontal axis of the element that you want displayed in the upper left. | ||
| - `yCoord` | ||
| - : The pixel along the vertical axis of the element that you want displayed in the | ||
| upper left. | ||
| - : The pixel along the vertical axis of the element that you want displayed in the upper left. | ||
| - `options` | ||
| - : An object containing the following properties: | ||
| - `top` | ||
| - `top` {{optional_inline}} | ||
| - : Specifies the number of pixels along the Y axis to scroll the window or element. | ||
| - `left` | ||
| - `left` {{optional_inline}} | ||
| - : Specifies the number of pixels along the X axis to scroll the window or element. | ||
| - `behavior` | ||
| - : Determines whether scrolling is instant or animates smoothly. This option is a string which must take one of the following values: | ||
| - `smooth`: scrolling should animate smoothly | ||
| - `instant`: scrolling should happen instantly in a single jump | ||
| - `auto`: scroll behavior is determined by the computed value of {{cssxref("scroll-behavior")}} | ||
| - `behavior` {{optional_inline}} | ||
| - : Determines whether scrolling is instant or animates smoothly. This option is a string that must take one of the following values: | ||
| - `smooth`: The scrolling animates smoothly. | ||
| - `instant`: The scrolling happens instantly in a single jump. | ||
| - `auto`: The scroll behavior is determined by the computed value of the {{cssxref("scroll-behavior")}} CSS property on the element. | ||
|
|
||
| If omitted, `behavior` defaults to `auto`. | ||
|
|
||
| ### Return value | ||
|
|
||
| None ({{jsxref("undefined")}}). | ||
| A {{jsxref("Promise")}} that fulfills with an object containing the following property: | ||
|
|
||
| - `interrupted` | ||
| - : A boolean value indicating whether the scrolling operation was interrupted (`true`) or not (`false`). Such an interruption typically happens when a programmatic scroll is ongoing, and another programmatic scroll is initiated on the same element before the first one finishes. | ||
|
|
||
| ## Examples | ||
|
|
||
| ### Basic usage | ||
|
|
||
| ```js | ||
| // Put the 1000th vertical pixel at the top of the element | ||
| element.scroll(0, 1000); | ||
|
|
@@ -60,6 +63,129 @@ element.scroll({ | |
| }); | ||
| ``` | ||
|
|
||
| ### Responding to the end of the scroll | ||
|
|
||
| Our [element methods demo](https://mdn.github.io/dom-examples/scroll-promises/element-methods/) ([see source code](https://github.com/mdn/dom-examples/tree/main/scroll-promises/element-methods)) demonstrates how the promise return value of `scroll()` can be used to respond to the end of a scrolling operation. This technique is mostly useful in cases where the scrolling occurs smoothly over time (achieved by setting the [`behavior`](#behavior) option to `smooth`, or by setting the scrolling element's {{cssxref("scroll-behavior")}} property to `smooth`). | ||
|
|
||
| #### HTML | ||
|
|
||
| Our HTML includes a {{htmlelement("section")}} element containing several paragraphs of content and a {{htmlelement("div")}} element toolbar containing {{htmlelement("button")}} elements that trigger various scrolling operations on the `<section>`. | ||
|
|
||
| ```html | ||
| <div> | ||
| <button class="scroll">scroll() to 1000</button> | ||
| <button class="scrollto">scrollTo() top</button> | ||
| <button class="scrollby">scrollBy() 200</button> | ||
| <button class="scrollintoview">Scroll last <p> into view</button> | ||
| </div> | ||
|
|
||
| <section>...</section> | ||
| ``` | ||
|
|
||
| #### CSS | ||
|
|
||
| We give the `<section>` element a fixed {{cssxref("height")}} and an {{cssxref("overflow-y")}} value of `scroll` so that it scrolls vertically, and set its {{cssxref("scroll-behavior")}} property to `smooth` so that any scroll operations are animated smoothly over time rather than instantly. | ||
|
|
||
| ```css | ||
| section { | ||
| border: 1px solid black; | ||
| padding: 20px; | ||
| margin-top: 60px; | ||
| height: 500px; | ||
| overflow-y: scroll; | ||
| scroll-behavior: smooth; | ||
| } | ||
| ``` | ||
|
|
||
| We also create two class selectors; when a `fade-out` or `fade-in` class is applied to an element, an {{cssxref("animation")}} is applied so that it smoothly fades out or in, respectively. We also define {{cssxref("@keyframes")}} blocks to define the required {{cssxref("opacity")}} changes for those animations. | ||
|
|
||
| ```css | ||
| .fade-out { | ||
| animation: fade-out 0.3s linear both; | ||
| } | ||
|
|
||
| .fade-in { | ||
| animation: fade-in 0.3s linear both; | ||
| } | ||
|
|
||
| @keyframes fade-out { | ||
| from { | ||
| opacity: 1; | ||
| } | ||
|
|
||
| to { | ||
| opacity: 0; | ||
| } | ||
| } | ||
|
|
||
| @keyframes fade-in { | ||
| from { | ||
| opacity: 0; | ||
| } | ||
|
|
||
| to { | ||
| opacity: 1; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The rest of the CSS is not shown, for brevity. | ||
|
|
||
| #### JavaScript | ||
|
|
||
| We start by grabbing references to the `<button>` that runs the `scroll()` operation, the toolbar `<div>`, and the scrolling `<section>`: | ||
|
|
||
| ```js | ||
| const scrollBtn = document.querySelector(".scroll"); | ||
| const toolbar = document.querySelector("div"); | ||
| const section = document.querySelector("section"); | ||
| ``` | ||
|
|
||
| Next, we define a function called `isInterrupted()`, designed to run in response to a scroll operation finishing, which takes a boolean `interrupted` value as a parameter. It logs a message to the console to say that scrolling is finished and indicate whether the operation was interrupted (`interrupted` is `true`) or not. In addition, if `interrupted` is `true`, it calls an `alert()` to clearly indicate the interruption. | ||
|
|
||
| ```js | ||
| function isInterrupted(interrupted) { | ||
| console.log(`Scroll finished;${interrupted ? " " : " not "}interrupted`); | ||
| if (interrupted) { | ||
| alert("Scroll interrupted!"); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| When the button is clicked, we immediately apply the `fade-out` class to the toolbar, causing it to fade out. We then run `scroll(0, 1000)` on the `<section>` to scroll its content down 1000 pixels, `await`ing its promise resolution as we do so and storing the `result` in a constant. When the promise has resolved, we call `isInterrupted()` to report that the scroll operation has finished and whether it was interrupted. Finally, we apply the `fade-in` class to the toolbar, causing it to fade back in again. | ||
|
|
||
| ```js | ||
| scrollBtn.addEventListener("click", async () => { | ||
| toolbar.className = "fade-out"; | ||
| const result = await section.scroll(0, 1000); | ||
| isInterrupted(result.interrupted); | ||
| toolbar.className = "fade-in"; | ||
| }); | ||
|
Comment on lines
+157
to
+163
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ditto everywhere.,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I will update the example description on each page to match the changes I've made to the example repo before passing this back to you again.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK; descriptions and code snippets updated as per the dom-examples changes. |
||
| ``` | ||
|
|
||
| The code not relevant to `scroll()` is not shown, for brevity. | ||
|
|
||
| #### Result | ||
|
|
||
| Click the buttons to see the scrolling behavior. Note how the toolbar fades out when a button is pressed, and fades in again once the smooth scrolling is finished. Also try pressing one button and then quickly pressing another button before the first scrolling operation has finished. Note how, in these cases, the scrolling is reported as interrupted. | ||
|
|
||
| {{EmbedGHLiveSample("dom-examples/scroll-promises/element-methods/", "100%", 620)}} | ||
|
|
||
| You can also [load the demo in a separate tab](https://mdn.github.io/dom-examples/scroll-promises/element-methods/) and view the [source code](https://github.com/mdn/dom-examples/tree/main/scroll-promises/element-methods). | ||
|
|
||
| #### Aside on feature detection | ||
|
|
||
| If you run this example in a browser that doesn't support promise-returning scroll operations, the scroll operations are still smooth, but the toolbar doesn't fade out and then fade back in once the operation is finished. The feature detection is handled by a function called `supportsScrollPromises()`, which runs a scroll operation and tests whether its return value is a promise: | ||
|
|
||
| ```js | ||
| function supportsScrollPromises() { | ||
| const test = section.scroll(0, 0); | ||
| return test instanceof Promise; | ||
| } | ||
| ``` | ||
|
|
||
| Check out the [source code](https://github.com/mdn/dom-examples/blob/main/scroll-promises/element-methods/index.js) to see how the feature detection is used. | ||
|
|
||
| ## Specifications | ||
|
|
||
| {{Specifications}} | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.