This function has been briefly described before. This time, we will explain the principles and existing problems in detail (since it uses the new API of html5, there are compatibility issues, so it is recommended that the mobile terminal use this method).
Function description:
Create a new tab page in the browser and specify a URL. After the web page is loaded, clicks are not allowed to return under the normal process. Because there is no relevant history of the current tab page, no records can be returned.
In response to the customer's request, in this case, add a link (such as the homepage) to his history record, so that on the newly opened page, click to return, you can jump to the homepage, allowing users to see the various functions of the system and promote the platform.
1. Key points of knowledge
HTML5 introduces the history.pushState() method and history.replaceState() method, which allow you to add and modify history entries item by item. These methods can work together with the window.onpopstate event.
Case:
Assume http://mozilla.org/foo.html will execute the following JavaScript code:
The code copy is as follows: var stateObj = { foo: "bar" }; history.pushState(stateObj, "page 2", "bar.html");
This will make the browser's address bar show http://mozilla.org/bar.html , but the bar.html page will not load nor check if bar.html exists.
Suppose that the user now navigates to http://google.com and then clicks the back button. At this time, the address bar will display http://mozilla.org/bar.html , and the page will trigger the popstate event. The state object in the event contains a copy of stateObj. The page looks like foo.html, although the page content may be modified in the popstate event.
If we click the back button again, the URL will change back to the http://mozilla.org/foo.html document to trigger another popstate event, this time the status object is null. Fallback will also not change the content of the document.
pushState() method
pushState() has three parameters: a state object, a title (which will be ignored now), and an optional URL address. Let’s examine the details of these three parameters separately:
State object - A JavaScript object associated with a new history entry created with the pushState() method. Whenever the user navigates to the newly created state, the popstate event is triggered, and the state property of the event object contains a copy of the state object of the history entry.
Any serializable object can be treated as a state object. Because the FireFox browser saves state objects to the user's hard disk, so that they can be restored after the user restarts the browser, we forcibly limit the size of the state objects to 640k. If you pass a state object exceeding this limit to the pushState() method, the method will throw an exception. If you need to store large amounts of data, it is recommended to use sessionStorage or localStorage.
Title - FireFox browser currently ignores this parameter, although it may be used in the future. Considering that this method may be modified in the future, it will be safer to pass an empty string. Alternatively, you can also pass in a short title indicating the status you are about to enter.
Address (URL) - The address of the new history entry. The browser does not load the address after calling the pushState() method, but afterwards, it may attempt to load, such as the user restarts the browser. The new URL is not necessarily an absolute path; if it is a relative path, it will be based on the current URL; the passed URL should be the same as the current URL, otherwise, pushState() will throw an exception. This parameter is optional; if not specified, it is the current URL of the document.
Note: In Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1) to Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), the passed objects are serialized using JSON. Starting with Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3), objects are serialized using a structured copy algorithm. This will allow more types of objects to be passed in safely.
In a sense, calling pushState() is a bit similar to setting window.location='#foo', and they all create and activate new history entries within the current document. But pushState() has its own advantages:
1. The new URL can be any homologous URL. In contrast, when using the window.location method, only modifying hash can ensure that it stays in the same document.
2. Decide whether to modify the URL according to your personal needs. Instead, set window.location='#foo' and create a new history only if the current hash value is not foo.
3. You can add abstract data to new history entry. If you use a hash-based method, you can only transcode the relevant data into a very short string.
Note that the pushState() method will never trigger the hashchange event, even if the new address only changes hash.
popstate event
The popstate event is triggered whenever the activated history changes. If the activated history entry is created by pushState or affected by the replaceState method, the status attribute of the popstate event will contain a copy of the history's status object.
replaceState() method
The history.replaceState() operation is similar to history.pushState(), except that the replaceState() method will modify the current history entry instead of creating a new entry.
When you want to update the status object or URL of the current history entry in response to certain actions by the user, using the replaceState() method is particularly suitable.
2. Implementation ideas
1. Use the popstate event to listen to click and return event.
2. When the event is triggered, determine whether there is a page to return the history of the current page.
3. If there is no page that can be returned, two records are inserted:
1) The specified jump page.
2) Empty record. (Make the current page not change)
Implementation method
//Return to the home page without a page before returning function pushHistory() { if (history.length < 2) { var state = { title: "index", url: getHttpPrefix + "index.html" }; window.history.pushState(state, "index", location.href); state = { title: "index", url: "" }; window.history.pushState(state, "index", ""); } //lll("history.state" + history.state) //console.log(history.state) }Determine the number of records in the current history. Since the browser will automatically push a record when the page is loaded. So we need to determine whether the length is less than 2.
The state object stuffed into is to get the corresponding URL link.
Note:
I put the jump url into the state object for the first pushState to facilitate jump operation. The second parameter has no practical significance, because the current browser basically does not apply this parameter.
The third parameter will replace the link in the current address bar, but the page will not jump. (I made a mistake before, setting the third parameter to the homepage link, which caused the address bar to be changed to the homepage link, so that the links on the current page are redirected based on the homepage, resulting in the error of all links on the page being redirected.)
setTimeout(function () { pushHistory() window.addEventListener("popstate", function (e) { lll("popstate"+window.history.state) if (window.history.state != null && window.history.state.url != "") { location.href = window.history.state.url } }); }, 300);This code is placed in the ready event of the page, with a delay of 300 milliseconds to lag the operation and prevent conflicts with the system pop event.
In order to determine whether history has a state object, only records that meet our requirements will have the state object we added, so the page jump operation can be performed based on this point.
This will achieve the effect we want.
4. Write at the end
shortcoming:
1. Obviously, as mentioned at the beginning. Only suitable for browsers that support html5.
2. Since two records were inserted, the return of mobile terminals like WeChat requires two clicks to return before launching the page and returning to the WeChat chat window, which has a poor user experience.
Summarize:
This method can definitely be optimized and improved, but my strength is not enough to be perfected to the level of perfection.
I hope that friends who read this article can get some inspiration, or there are better ways to achieve it.