Preface
1. Mainly return is the default browser return event is to return to the previous page.
2. Processing all kinds of pop-ups on the page, clicking on physical return should hide these pop-ups instead of returning directly to the page.
3. To sum up the problems, h5 should hope to monitor the return events and do some processing.
Related knowledge
1. Using the popstate event, click on the browser to move forward, and back will trigger the popstate event.
2. Using hashchange event, page hash change will trigger this event (suitable for react, vue single page application).
I. window.onpopstate
Whenever the history entry in the active state changes, the popstate event triggers on the corresponding window object. If the current active history entry is created by the history.pushState() method or modified by the history.replaceState() method, the state attribute of the popstate event object contains a copy of the state object of the history entry. Bei.
Calling history.pushState() or history.replaceState() does not trigger the popstate event. The popstate event will only trigger under certain browser actions, such as clicking the back and forward buttons (or calling history.back(), history.forward(), history.go() methods in JavaScript).
history.pushState() does not refresh the page, adding a record to the history.
history.replaceState() does not refresh the page, replace the current page record, and do not add new pages to the history.
Compatibility: When a web page is loaded, browsers have different behaviors on whether popstate events are triggered. Chrome and Safari trigger popstate events, while Firefox does not.
Reference to related documents.
If the current page address is example.com/example.htm… After running the following code:
window.onpopstate = () => {} Equate to window.addEventListener('popstate',() => {}); window.onpopstate = function(event) { alert("location: " + document.location + ", state: " + JSON.stringify(event.state)); }; //Bind event handlers. history.pushState({page: 1}, "title 1", "?page=1"); //Add and activate a history entry http://example.com/example.html?page=1, with two records (including the first) indexed to the current record of the entry. history.pushState({page: 2}, "title 2", "?page=2"); //Add and activate a history entry http://example.com/example.html?page=2, with an entry index of 2 and three records for the current record history.replaceState({page: 3}, "title 3", "?page=3"); //Modify the currently activated history entry http://ex.page=2 to http://ex.page=3, and the entry index is three for the current record (replaceState replaces Article 3). history.back(); // Pop up "location: http://example.com/example.html?page=1, state: {"page":1}" history.back(); // Pop up "location: http://example.com/example.html, state: null" history.go(2); // Pop up "location: http://example.com/example.html?page=3, state: {"page":3} Copy code
As shown above, assuming that the current page is page A, jump to page B, and page B opens the dialong pop-up window. At this time, click back, and by default return to page A. This experience is very poor, optimize the experience, this time need to optimize the performance of this experience.
Scenario: There is a pop-up window on page B. Click back. To close the pop-up window, click again and return to page A.
The code is as follows:
// Assume that page A is http://www.example.com/a.html // The B page is http://www.example.com/b.html. // Take the react life cycle as an example componentDidMount: function() { window.addEventListener('popstate',(state) => { // Listen for the return event. Note that this method will only be executed if the return is triggered. console.log(state); this.back(); }) } // Suppose you click to open the dialog window and use pushState to add a day's record openDialong: function() { // At this point, the page address is b.html?page=1, but the page is not refreshed. And it does not trigger the popstate method history.pushState({page: 1}, "title 1", "?page=1"); // TODO } // The pop-up window already exists and clicks on the return event, when the page b.html? Page = 1 - > b.html, and triggers the popstate event back: function() { // The page is not refreshed in the user's view, and the dialong is closed at this time. // TODO } // Cancel listening for popstate when leaving the page componentWillUnmount: function() { window.removeEventListener('popstate',(state) => { this.back(); }) }Copy code
II. window.onhashchange
The hashchange event is triggered when the hash of a window (the part after # in the URL) changes (see location.hash).
if ("onhashchange" in window) { alert("This browser supports hashchange events!"); } function locationHashChanged() { if (location.hash === "#somecoolfeature") { somecoolfeature(); } } window.onhashchange = locationHashChanged; copy code
Or take the above scenario as an example:
// Assume that page A is http://www.example.com/a.html#/a // Page B is http://www.example.com/a.html#/b // Take the react life cycle as an example componentDidMount: function() { window.addEventListener('hashchange',(state) => { // The hash change will trigger const href = location.href; // Does not exist in the current hash? page=1 is triggered (the method is not triggered when the initialization just comes in) if (href.indexOf('?page=1') < 0) { this.back(); } }) } // Suppose you click to open the dialog window and use pushState to add a day's record openDialong: function() { // At this point, the page address is a.html?page=1, but the page is not refreshed. And it does not trigger the popstate method // history.pushState({page: 1}, "title 1", "?page=1"); // At this point, however, hashchange is triggered, but a judgment is added. this.props.history.push('/b?page=1'); // TODO } // The pop-up window already exists and clicks on the return event, when the page a.html? Page = 1 - > a.html, and triggers the hashchange event back: function() { // The page is not refreshed in the user's view, and the dialong is closed at this time. // TODO } // Cancel listening for hashchange when leaving the page componentWillUnmount: function() { window.removeEventListener('hashchange',(state) => { this.back(); }) } Copy code
III. OPTIMIZATION**
Or this picture
Suppose A is the home page, B is the details page, C is the payment page, D is the result page. We hope D can't return to page C.
Suppose you want to jump from D page to B page (B,C,D is the same), and from the result page D click the button to jump to Details B page, you can buy again.
There are the following methods:
Method 1: Location.href = http://www.example/b.html'; Method 2: history.go(-2); duplicate code
Main differences:
Methods A new record was added to the historical record, which became A - > B - > C - > D - > B.
At this point, click Physical Return, and you will return to page D. And that's not what we want.
The second method is to return to the historical records without adding new records. Links are still A - > B - > C - > D.
D page should not go back to C page
At this point, we can use the above method, click back to use history.go() method, back to the page we thought of.
// Page D - > Page B componentDidMount: function() { this.props.history.push('/b?page=1'); // If there is a problem, add a setTimeout window.addEventListener('hashchange',(state) => { // The hash change will trigger const href = location.href; // Does not exist in the current hash? page=1 is triggered (the method is not triggered when the initialization just comes in) if (href.indexOf('?page=1') < 0) { this.back(); } }) } // And click on the return event, when the page D. html? Page = 1 - > D. html, and trigger the hashchange event back: function() { // The page is not refreshed in the user's view, and then it is back to page B. // TODO this.props.history.go(-2); } // Cancel listening for hashchange when leaving the page componentWillUnmount: function() { window.removeEventListener('hashchange',(state) => { this.back(); }) }Copy code
If you have any questions, please correct them.
Author: _forever
Link: https://juejin.im/post/5b603c94e51d4519700f84a1
Source: Nuggets
Copyright belongs to the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.