Implementation principle of two main methods of front-end routing

Original Link: https://segmentfault.com/a/1190000007238999

Early routes were implemented on the back end, reload ing pages based on url caused great pressure on the back end as the page became more and more complex. In order to alleviate background pressure and front end user experience, the method of partial refresh of view, ajax, appeared, and laid a foundation for front end routing.Record changes in Ajax by recording changes in url (tagging of ajax) to implement front-end routing.

1. H5 New Hiistory API

The focus is on the history.pushState() and history.replaceState() API s

Both API s receive three parameters:
State object - A JavaScript object associated with a new history entry created with the pushState() method.Whenever a user navigates to a 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.
Title - FireFox browsers currently ignore this parameter, although it may be used later.Given that this method may be modified in the future, it is safe to pass an empty string.Alternatively, you can pass in a short title indicating the status you are about to enter.
Address (URL) - The new history entry destination address.The browser does not load the address after calling the pushState() method, but it may try to load later, such as when 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 incoming URL should be homologous to the current URL, or pushState() will throw an exception.This parameter is optional; if not specified, it is the current URL of the document.
The same thing is that both API s operate on the browser's history without causing a page refresh.

The difference is that pushState adds a new history and replaceState replaces the current one.

Our console for Baidu in Canada is an example (specifically, my browser opens the console on the first page of Baidu.)

We enter it in the console

window.history.pushState(nullnull"https://www.baidu.com/?name=orange");

Okay, let's see how the url looks at this point

We don't have a test here, just give you another usage, try it yourself

window.history.pushState(null, null, "https://www.baidu.com/name/orange");
//url: https://www.baidu.com/name/orange

window.history.pushState(null, null, "?name=orange");
//url: https://www.baidu.com?name=orange

window.history.pushState(null, null, "name=orange");
//url: https://www.baidu.com/name=orange

window.history.pushState(null, null, "/name/orange");
//url: https://www.baidu.com/name/orange

window.history.pushState(null, null, "name/orange");
//url: https://www.baidu.com/name/orange

Note: The url here does not support cross-domain, and errors will occur when we change www.baidu.com to baidu.com.

Back in the example above, the url page is not refreshed each time it changes, and the browser generates a history as described above

This is the premise of changing the url without refreshing the page. Let's talk about the first parameter, the state object.If you run the history.pushState() method, the record corresponding to the history stack is stored in the state object, and we can call the history entry actively at any time.An example of mozilla is quoted here

<!DOCTYPE HTML>
<!-- this starts off as http://example.com/line?x=5 -->
<title>Line Game - 5</title>
<p>You are at coordinate <span id="coord">5</span> on the line.</p>
<p>
 <a href="?x=6" onclick="go(1); return false;">Advance to 6</a> or
 <a href="?x=4" onclick="go(-1); return false;">retreat to 4</a>?
</p>
<script>
 var currentPage = 5; // prefilled by server!!!!
 function go(d) {
     setupPage(currentPage + d);
     history.pushState(currentPage, document.title, '?x=' + currentPage);
 }
 onpopstate = function(event) {
     setupPage(event.state);
 }
 function setupPage(page) {
     currentPage = page;
     document.title = 'Line Game - ' + currentPage;
     document.getElementById('coord').textContent = currentPage;
     document.links[0].href = '?x=' + (currentPage+1);
     document.links[0].textContent = 'Advance to ' + (currentPage+1);
     document.links[1].href = '?x=' + (currentPage-1);
     document.links[1].textContent = 'retreat to ' + (currentPage-1);
 }
</script>

Let's click Advance to?The corresponding url and template will both + 1, otherwise click retreat to?Will all-1, which meets the need for url to change with the template view

Actually, we don't need to simulate onpopstate events. Official documents provide popstate events, which occur when we switch in the history.Browser implementations also differ in the way popstate events are triggered, and we can handle them compatibly according to different browsers.

2,hash

We often see # in url s. There are two cases of this #. One is what we call an anchor point, such as the typical back-to-top button principle, the jump between headings on Github, etc. The # in a route is not called an anchor point, which we call hash. Most of the routing systems of large frameworks are implemented by hashing.

We also need an event triggered by listening for hash changes - the hashchange event

When we use window.location to handle hash changes, instead of re-rendering the page, we add it to the history as a new page so that we can jump to the page and register ajax in the hashchange event to change the page content.

hashchange needs to be polled for url changes in lower versions of IE, and we can simulate the following:

(function(window) {

  // If the browser does not support natively implemented events, start the simulation or exit.
  if ( "onhashchange" in window.document.body ) { return; }

  var location = window.location,
  oldURL = location.href,
  oldHash = location.hash;

  // Check hash for changes every 100ms
  setInterval(function() {
    var newURL = location.href,
    newHash = location.hash;

    // hash has changed and the onhashchange method is globally registered (this name is used to unify with the simulated event name);
    if ( newHash != oldHash && typeof window.onhashchange === "function"  ) {
      // Execution Method
      window.onhashchange({
        type: "hashchange",
        oldURL: oldURL,
        newURL: newURL
      });

      oldURL = newURL;
      oldHash = newHash;
    }
  }, 100);
})(window);

Routing for large frameworks is certainly not that simple. The routes for angular 1.x associate hashes, templates, and processors, roughly as follows:

app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
 $routeProvider
 .when('/article', {
   templateUrl: '/article.html',
   controller: 'ArticleController'
 }).otherwise({
   redirectTo: '/index'
 });
 $locationProvider.html5Mode(true);
}])

This routing scheme defaults to hashing starting with #. If you don't consider a lower version browser, you can call $locationProvider.html5Mode(true) directly to take advantage of the H5 scheme without hashing.

The hash scenario is recommended for both scenarios, because considering the low-level browser, it is not ugly (one more#), neither of them is necessary. We can only judge if the browser gives the corresponding scenario, but it only supports IE8+. The lower version is compatible with the above!


Keywords: Javascript Firefox github IE

Added by Derokorian on Tue, 14 May 2019 22:28:05 +0300