Re: [whatwg] beforepopstate event?

<CAEayHENYe7wjG5v7zFqG49SNLBsi8X-iTXXJNdCrdftG7p1jkA@mail.gmail.com>

Current votes: None.

On Thu, Jan 26, 2012 at 11:30 PM, Ian Hickson <ian@hixie.ch> wrote:
> On Sun, 25 Sep 2011, Thomas Broyer wrote:
>>
>> Is there really no equivalent to the beforeunload event for the History
>> API? Has it been discussed? or is this an oversight?
>
> Does the "pagehide" event do what you mean?

I don't think so (unless I misunderstood the spec).

A common use case for beforeunload is to prompt the user before
leaving when it has unsaved changes. For instance, you edited a mail
draft, updated the phone number of a contact, or filled any kind of
form, but you didn't save your changes; when you "navigate away",
beforeunload can be used to prompt you whether you really want to go
(and lose your changes).

Within a "single-page app", where you use location.hash=xxx and
hashchange, or pushState() and popstate, to handle the navigation,
there doesn't seem to be any way to prompt the user and possibly
*cancel* the navigation. Something like:
1. you're looking at your mail inbox, and click on "new mail"
2. you type in some text
3. you click on the "previous page" button of your browser, or trigger
an equivalent action using a keyboard shortcut (possibly mistakenly)
As the app developer, I'd like to be able to prompt the user whether
he really want to go (and lose his changes), and if he actually wants
to continue editing his mail draft (and/or save it before navigating
again), then *cancel* the "history traversal"; in a similar way as if
I developed a "multi-page app" (or if he'd close the window/tab or
navigate away from the app): I could then do that using the
beforeunload event, either cancelling it or setting its returnValue to
some non-empty string value.

AFAICT, no pagehide event would be fired in this case (traversing
history, staying on the same Document, only changing its location.hash
or history.state).

Unless I missed something, all I can do is to handle the hashchange or
popstate event and use Window.confirm() or similar, and only update
the page from the location.hash or history.state if he confirms; but
then navigation has already taken place, I cannot cancel the
navigation but only "ignore" it. That means the current state of the
app as reflected in window.location and/or history.state is not in
sync with what the user sees (the "actual" state of the app), which
also means that if he creates a bookmark (or copy the URL) at this
point, when loading it again later, the app won't show what he saw
when he created the bookmark (because it has no way to know about
that).

Note that I previously only asked about pushState/popstate because I
think this is what app developers should use for such in-app
navigation, rather than local.hash/hashchange.