Ecma262: Add callback option to `scrollIntoView()` and `window.scroll()`

Created on 12 Dec 2019  路  3Comments  路  Source: tc39/ecma262

The problem

Currently, if we use element.scrollIntoView({ behavior: 'smooth', block: 'start' }), the screen will scroll but we have no way of telling when the screen has stopped scrolling.

An accessibility requirement of smooth scrolling in-page links is that we apply focus to the target element when the screen has stopped scrolling. We can't do that easily at the moment. We have to use an arbitrary setTimeout value (I typically use 500 milliseconds).

More details about the accessibility issues when smooth scrolling can be read about in this CSS Tricks article:
https://css-tricks.com/smooth-scrolling-accessibility/

It makes specific mention of native smooth scrolling here:
https://css-tricks.com/smooth-scrolling-accessibility/#article-header-id-4

Proposed solution

Add a callback option to the options object that is triggered at the end of the scroll event.

element.scrollIntoView({ behavior: 'smooth', block: 'start', callback: scrollEvent => {
  console.log('The browser has finished scrolling')
}})

This should also be applied to window.scroll

window.scroll({ top: 0, left: 0, behavior: 'smooth', callback: scrollEvent => {
  console.log('The browser has finished scrolling')
}})

Most helpful comment

I would actually prefer the scroll events to return a Promise object so that I can run a .then() call on it or an await call to wait until it has finished scrolling.

applied to element.scrollIntoView

element.scrollIntoView({ behavior: 'smooth', block: 'start').then( scrollEvent => {
  console.log('The browser has finished scrolling')
})

applied to window.scroll

window.scroll({ top: 0, left: 0, behavior: 'smooth').then( scrollEvent => {
  console.log('The browser has finished scrolling')
})

I think that might break backwards compatibility though. That is why I suggested a callback option instead.

All 3 comments

I would actually prefer the scroll events to return a Promise object so that I can run a .then() call on it or an await call to wait until it has finished scrolling.

applied to element.scrollIntoView

element.scrollIntoView({ behavior: 'smooth', block: 'start').then( scrollEvent => {
  console.log('The browser has finished scrolling')
})

applied to window.scroll

window.scroll({ top: 0, left: 0, behavior: 'smooth').then( scrollEvent => {
  console.log('The browser has finished scrolling')
})

I think that might break backwards compatibility though. That is why I suggested a callback option instead.

@Dan503 You are on the wrong repo: scrollIntoView is not part of ECMAScript (the core language), but of CSSOM. You may be interested in this: https://github.com/w3c/csswg-drafts/issues/3744

Yep, that basically covers the problem I have with the existing scroll functions.

Was this page helpful?
0 / 5 - 0 ratings