-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
scrollRestoration & popstate #1042
Comments
Paging @majido and @smaug---- for opinions. |
As you pointed out, the fundamental problem is that when the popstate event is dispatched we have access only to the current history entry and not the previous one. For the usecase of storing scroll position what I have tended to do is to maintain a map of scroll position outside of the state object associated with the entry. Here is a simplified example that stores it in memory. In fact saving the state elsewhere is a well know solution. This does not address the fundamental limitation but gets the job done. Another alternative that we have considered that can help with this is to actually expose the browser recorded scroll position.
It feels wrong to me to have a different timing for I have seen similar 'onLeave' hooks provided by routing frameworks used on the web. So there is some indication of a need here. I am not sure if this is evidence enough to justify a new event though. |
You are not supposed to be able to see the history state of any other page. That would be a security/privacy issue. I agree with majido that a |
Could popstate event contain more information? like oldState or so, would that help here? |
I think this is a misunderstanding—no one's proposed changes involve seeing the history state of another page. My proposal was if you did |
Makes sense, I had an inkling of this kind of workaround like this last night but was too tired to try it. We’re all in agreement that there is a problem here that currently has to be worked-around, though, right?
I think this can address the fundamental limitation, the problem was my use-case-specific choice of tying it to scroll restoration mode. I too am not a fan of piling onto our ever-growing list of DOM events. I think it's worth noting how odd the current default behavior is ( Also, there used to be With all that in mind, I propose a
I'd also be happy if this could be tied to something like the next DOCTYPE, but I assume that's out of the question? |
IIRC I filed a spec bug to make spec to follow implementations. |
That wouldn't help with the example I gave, where the API consumer expects to be able to save information to the current history state with Also, MDN on
It's only implemented in latest Firefox and Chrome but not in Safari or IE/Edge, I hope it's not too late? I'm proposing a change to it here, after all.
Mind if I ask for a link? |
a change is fine, but re-designing the scrollRestoration to be fully events based, may not be. But, ok, perhaps at this point the safest, though a bit ugly approach is to explicitly just dispatch a simple event 'beforepopstate' somewhere before step 12 in https://html.spec.whatwg.org/multipage/browsers.html#history-traversal |
Exactly! Exactly the behavior I'm proposing for values of |
We spent a lot of time trying to make an event-based API work. I even wrote an initial draft spec but we ran into a fundamental issue on having this event-based API work for cross-doc navigations where scroll position should be restored content scripts are loaded. The reason an event works in this situation is because the problem you are trying to fix is only manifest in same-doc navigation case.
I think you are referring to #39 which proposes that we match spec with actual implementations: Actual implementations: If I understand @laughinghan proposal correctly, 1- The event dispatch timing may now be before/after the actual event and is determined based on a dynamic value. I cannot think of any other event that has this property. It means that to reliably use this event the developer has to check this value and behave accordingly. Imagine if a third-party library changes this value! 2- This fixes the problem of accessing the previous state before transition but now you don't have access to upcoming state. The best solution I can think of is to use a Also the naming is odd. What you are describing is should require two state
Yes, I think dispatching event before action makes sense specially when event is cancelable. But that ship has sailed long ago for
Well, that is a good precedent specially when it comes to navigation related events. There is also I agree that adding a new event shouldn't be taken lightly but I don't see how the proposed solution is any better. Any other ideas? |
What if the scroll position was kept in the history state automatically as a read-only variable, even when |
See my earlier comment on this. This is a good solution for the specific usecase of scroll position. I am inclined to think that there is more long-term value for web platform, if we spend the effort instead and attempt to fix the more fundamental issue here i.e., accessing the state before and after a history navigation. That actually makes history.state a viable option to store page state. |
@majido: Thank you for your detailed responses :) the crazy
|
Currently (in Chrome 48 and Firefox 45 at least), if you go to this page and:
...you will end up at “N. David Tilton” again, because the browser remembers the scroll position at the time you hit the Back button.
Now say you want to replicate that behavior but with smooth scrolling, using
history.scrollRestoration = 'manual'
. The natural way to do this is for your handler for thepopstate
event to use the session objects:For that to work, your click handler for the link has to save the current scrollTop before smooth-scrolling to the target:
That makes the Back button work. But to make the Fwd button work like in the example above, your popstate handler also has to save the current
scrollTop
:(Ending up with this.)
And therein lies the problem: by the time
popstate
has fired, the state has already been popped, and rather than writing to the history entry from before hitting the Back button like we want to make the Fwd button work, that history entry is first popped off andhistory.replaceState()
writes to the history entry underneath that, after we’ve gone Back.Now,
popstate
has been around forever, so we can’t just brazenly make breaking changes to it. But,scrollRestoration
isn't even yet supported by all browsers. What if settinghistory.scrollRestoration = 'manual'
causedpopstate
to fire before the history entry has been popped off? Note that this would also be more consistent with the vast majority of DOM events likekeydown/keypress/keyup/mousedown/mouseup/click
, all of which fire before the relevant action (and they necessarily must so that you can cancel that action withpreventDefault()
).Test case (automated & manual) for the desired browser behavior: http://output.jsbin.com/talumi
The text was updated successfully, but these errors were encountered: