WICG / navigation-api

The new navigation API provides a new interface for navigations and session history, with a focus on single-page application navigations.
https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigation-api
487 stars 26 forks source link

Mismatch between scroll and focus handling #231

Closed jakearchibald closed 2 years ago

jakearchibald commented 2 years ago

The default focus behaviour is to reset focus, which is appropriate behaviour if the page is changing significantly, but not in cases like tabbed navigation.

This behaviour was decided in https://github.com/WICG/navigation-api/issues/202 to match MPA behaviour.

However, it seems like current scroll behaviour is out of step with this intent. In a regular MPA, when you navigate via either push/replace, scrolling is reset to 0,0. It feels like this should happen here too.

I'm not sure if this should be rolled into the current scroll option, or whether it needs a separate scrollReset option.

domenic commented 2 years ago

This came up in discussion with @annevk as well; it slipped out of my brain before I could file it. Thanks for finding this and bringing it up.

The desire for symmetry between scroll and focus is indeed what makes this hard. A quick fix would be to add a scrollReset option which only applies to push/replace/reload (or maybe only push??). And maybe that's the right thing to do. But if we want to take a step back the picture gets more complicated...

The cross-document nav experience is:

The current navigation API default experience for same-document navs is:

We've been treating focus restore as something that we can't do by default, because of the problem of identifying the "same" DOM element. That seems like a safe bet to me. But we could probably fix the scroll reset/restore behavior.

Proposal:

These are both compat-impacting changes. They would bring us to

The proposed navigation API default experience for same-document navs is:

which is close to the cross-document nav experience.

jakearchibald commented 2 years ago

Scroll resets on push/replace

The case I'm unsure about is hash-change navigations.

I'm happy with scrollReset as an option. The only reasons I thought about rolling them into one option is that scroll resetting is a little bit like a restoration, but it's restoring it to 0,0. You never get resetting and restoring happening on the same navigation.

domenic commented 2 years ago

The case I'm unsure about is hash-change navigations.

If you call transitionWhile() on a hashchange navigation, you are opting out of the usual navigate-to-a-fragment anyway. (This is why a lot of the demo code has if (!e.hashChange).)

Whereas, if anyone was using the hash to store information that was not a target element (e.g., UI state like which tab was open) they might want resetting behavior...

So I think it would be OK.

You never get resetting and restoring happening on the same navigation.

That's a good point, and it would be nice to unify. However:

These are not very strong objections, so if we can think of a good name it still might be better to combine.

jakearchibald commented 2 years ago

I can't think of a good name either. Given the above, it seems fine for them to be seperate options.

domenic commented 2 years ago

237 is about a different problem, but its solution will probably be part of the same API, and subsume what we're talking about here. So people interested should follow both issues.