w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.44k stars 657 forks source link

[cssom-view] Handling of scrollend events seems wrong #8396

Open zcorpan opened 1 year ago

zcorpan commented 1 year ago

https://w3c.github.io/csswg-drafts/cssom-view/#scrolling-events

Each Document has an associated list of pending scrollend event targets, initially empty.

Whenever scrolling is completed, the user agent must run these steps:​

If scrolling was done on a viewport, let doc be the viewport’s associated Document and target be the viewport\. Otherwise, scrolling is done on an element and let doc be the element’s node document and target be the element\.

If target is already in doc’s pending scrollend event targets, abort these steps\.

Append target to doc’s pending scrollend event targets\.

For each item target in doc’s pending scrollend event targets, in the order they were added to the list, run these substeps:​

    If target is a Document, fire an event named scrollend that bubbles at target\.

    Otherwise, fire an event named scrollend at target\.

Empty doc’s pending scrollend event targets\.

This setup doesn't make sense to me. As specified, the "pending scrollend event targets" can be optimized away since you add a single entry to it, then immediately process it, then empty the list, in the same algorithm.

But, at what point does the UA determine that scrolling is completed? If it's not done in "run the scroll steps", the spec may fire scrollend first and scroll afterwards. Or, if "scrolling is completed" happens in parallel (off-main-thread), then the spec says to fire an event in a situation where would instead have to queue an event to fire the event (which the spec doesn't say to do).

For scroll events, the "pending scroll event targets" list can be populated in parallel, and the "run the scroll steps" is called from HTML's event loop: https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering

I think the appropriate fix here is to move the "fire an event" and emptying of the queue for scrollend into "run the scroll steps" algorithm, after it has dealt with any scroll events.

cc @emilio @dlrobertson @argyleink

dlrobertson commented 1 year ago

But, at what point does the UA determine that scrolling is completed? If it's not done in "run the scroll steps", the spec may fire scrollend first and scroll afterwards. Or, if "scrolling is completed" happens in parallel (off-main-thread), then the spec says to fire an event in a situation where would instead have to queue an event to fire the event (which the spec doesn't say to do).

Similar to what is stated here, what is the expected behavior given a user scrolling with a mousewheel in a scenario where smooth scroll is disabled. Currently Firefox fires a scrollend event as soon as the mousewheel scroll completes, which results in many scrollend events for a series of mousewheel scrolls. Simple tests with chrome seem to indicate that scrollend events are a bit more aggressively coalesced.