preface

1. The main return is the default browser return event is to return to the previous page.

2. Handle various pop-ups on the page. Click physical Return to hide these pop-ups instead of returning to the page directly.

3. To summarize the problem, H5 should want to listen for the return event and do something about it.

The relevant knowledge

1. Using the PopState event, click the browser forward, back will trigger the PopState event.

Use the Hashchange event, which is triggered when a page hash changes (suitable for react, vue single-page applications).

A, window. Onpopstate

Whenever the active history entry changes, the popState event is fired on the corresponding Window object. If the currently active history entry was created by the history.pushState() method or modified by the history.replacestate () method, The state property of the POPState event object contains a copy of the state object for this history entry.

Calls to history.pushState() or history.replacEstate () do not trigger popState events. Popstate events are only triggered by certain browser actions, For example, click the back or forward button (or call the history.back(), history.forward(), or history.go() methods in JavaScript).

History.pushstate () does not refresh the page and adds a record to the history.

History.replacestate () does not refresh the page, replaces the current page record, and is not added to the history record.

Compatibility: when a web page loads, each browser pairspopstateWhether an event is triggered or not varies. Chrome and Safari firepopstateEvent, which Firefox does not.

Refer to relevant documentation.

If the current web address is example.com/example.htm… , then run the following code:

Window.onpopstate = () => {} equals window.addeventListener ('popstate', () = > {}); window.onpopstate =function(event) {
  alert("location: " + document.location + ", state: "+ JSON.stringify(event.state)); }; // bind the event handler function. History. pushState({page: 1},"title 1"."? page=1"); / / add and activate a history entry http://example.com/example.html?page=1, index entries for the current record 1 has two records (including the first) history. PushState ({2} page:,"title 2"."? page=2"); To add and activate a history entry / / http://example.com/example.html?page=2, item index for 2 the current record has three records history. ReplaceState ({3} page:."title 3"."? page=3"); // Modify the currently active history entry http://ex.. ? Page = 2 to http://ex.. ? Page =3, entry index =3 History.back (); / / the pop-up"location: http://example.com/example.html?page=1, state: {"page": 1}"history.back(); / / the pop-up"location: http://example.com/example.html, state: null history.go(2); / / the pop-up"location: http://example.com/example.html?page=3, state: {"page": 3}Copy the code


As shown in the figure above, assume that the current page is page A, jump to page B, and the Dialong popup window opens on page B. Click “Return” at this time, and return to page A by default. This kind of experience is very poor, optimize the experience, this time needs to optimize the experience performance problem.

Scene: There is A popover in page B, click back, close the popover, click again to return to page A.

The code is as follows:

/ / assume that A page is http://www.example.com/a.html / / B page is http://www.example.com/b.html / / react life cycle, for example componentDidMount below:function() {
    window.addEventListener('popstate'Console. log(state); console.log(state); console.log(state); console.log(state); this.back(); } // If you click open dialog, use pushState to add a record of the day openDialong:function() {// the page address is b.html? Page =1, but the page is not refreshed. The popState method history.pushState({page: 1},"title 1"."? page=1"); // TODO} // the popover already exists, and the return event is clicked, when the page b.html? Page =1-- >b.html and trigger the popState event back:functionPopstate componentWillUnmount () {// dialong // TODO // popState componentWillUnmount ();function() {
    window.removeEventListener('popstate',(state) => { this.back(); })}Copy the code

Second, the window onhashchange

The Hashchange event (see Location.hash) is emitted when a window’s hash (the part of the URL that follows the #) changes.

if ("onhashchange" in window) {
    alert("This browser supports the Hashchange event!");
}
​
function locationHashChanged() {
    if (location.hash === "#somecoolfeature") {
        somecoolfeature();
    }
}
​
window.onhashchange = locationHashChanged;Copy the code

Take the above scenario as an example:

/ / assume that A page for http://www.example.com/a.html#/a / / B page is http://www.example.com/a.html#/b ComponentDidMount = componentDidMountfunction() {
    window.addEventListener('hashchange',(state) => {
        // hashThat change triggers const href = location.href; / / the currenthashDoes not exist in? Page =1 is triggered (initialization does not trigger this method just in time)if (href.indexOf('? page=1') < 0) { this.back(); } // If you click open dialog, use pushState to add a record of the day openDialong:function() {// the page address is a.html? Page =1, but the page is not refreshed. // history.pushState({page: 1},"title 1"."? page=1"); // This will trigger a hashchange, but with a judgment; this.props.history.push('/b? page=1'); // TODO} // the popover already exists, and the return event is clicked, then the page a.html? Page =1-- > A.html and trigger the hashchange event back:function() {// dialong // TODO is closed; // When leaving the page, unlisten hashChange componentWillUnmount:function() {
    window.removeEventListener('hashchange',(state) => { this.back(); })}Copy the code

Three, optimize **


This is the same picture

Suppose A is the home page, B is the details page, C is the payment page, and D is the results page. (We want D not to return to page C).

If you want to jump from PAGE D to page B (B,C,D are the same), click the button from the result page D to go to page B for details and purchase again.

There are the following methods:

Location. Href ='http://www.example/b.html'; History. go(-2);Copy the code

Main differences:

The method then adds A new record to the history, becoming A – >B – >C – >D – >B.

At this point, click physics Back to return to page D. And that’s not what we want.

Method 2: Go back to the historical record, no new record is added, and the link is A >B >C >D.

Page D should not go back to page C

At this point we can use the above method and click back to use the history.go() method to return to the page we have in mind.

// D page ---->B pagefunction() {
    this.props.history.push('/b? page=1'); // If there is a problem, add asetTimeout
    window.addEventListener('hashchange',(state) => {
        // hashThat change triggers const href = location.href; / / the currenthashDoes not exist in? Page =1 is triggered (initialization does not trigger this method just in time)if (href.indexOf('? page=1') < 0) { this.back(); }})} // and click the return event, when the page d.html? Page =1-- >d.html and trigger the hashchange event back:function// TODO this.props.history.go(-1); // TODO this.props.history.go(-1); } // Unlisten hashChange componentWillUnmount when leaving the page:function() {
    window.removeEventListener('hashchange',(state) => { this.back(); })}Copy the code

You can view the compatibility.

Please point out any questions.