An article, impossible to do everything, all the audience. I hope everyone with divergent thinking to read the article, the article involved in the knowledge point, absorption for their own use. In this way, after reading an article, you can gain something.

preface

Ok no, today I will be a sexy interviewer online to ask you a question, “talk about your understanding of front-end routing”. There are a lot of answers to that question. But think about it. When you ask a candidate this question, what do you want to get? In my humble opinion, I would like the candidates to take a holistic view of the problem, which is roughly three things.

1. Why front-end routing occurs?

2. What problems front-end routing solves.

3. What is the principle of front-end routing implementation?

With these three questions in mind, we will continue to read on. If you have your own opinions during the reading, you can comment in the comments section. If you think what I have said has given you new insights, please send your precious praise 👍, which will be my motivation to continue writing.

Traditional page

I’m not going to bother with names here, but whenever the entire project is a DOM straight out page, we call it a “traditional page” (SSR is the first screen straight out, and I don’t think it’s a traditional page here). So what is DOM straight out? In simple terms, the browser initiates a request after input the url, and the HTML page returned is the final rendering effect, which is the DOM straight out. And every time you click the page jump, the HTML resource is requested again. Seeing is believing. Let’s use this address as an example to verify the following statement.

www.cnblogs.com/han-1034683…

It is easy to see what the picture above is describing. Yes, bloggarden is a website built from traditional pages. Every time a page is loaded, it returns HTML resources and static resources such as CSS, which are combined into a new page.

“Blind” students, I will teach a method, is in the browser page right click “show web source code”, open after the following:

What kind of images or text you can see on the page, you can find the corresponding HTML structure in the above image, which is also a traditional page, which is the DOM straight out.

Single page

Times in progress, the development of science and technology, in the face of increasing demand for web pages, web pages began to modular, componenzation of the road. The resulting code is difficult to maintain, uncontrollable, and difficult to iterate. This has led to a number of great modern front-end frameworks, starting with React, Vue, Angular, and other well-known single-page application frameworks. One common feature of these frameworks is “render the page with JS”.

For example, where we used to go straight out of the DOM, now with these single-page frames, the HTML page basically has only one ENTRY to the DOM, something like this:

All page components are mounted under the

node by running the app.js script at the bottom of the figure above. Show the mounting step with a very simple JS:
<body>
  <div id="root"></div>
  <script>
    const root = document.getElementById('root') // Obtain the root node
    const divNode = document.createElement('div') // Create div node
    divNode.innerText = 'What's your mother's name? ' // Insert content
    root.appendChild(divNode) // Insert the root node
  </script>
</body>
Copy the code

Stripped of all the mundane, this is the most authentic one-page project run. Attention, I want to point ah!!

Since a single page is rendered like this, what if I have a dozen pages that have to jump between each other!! ?? At this time front-end routing arises at the historic moment, its emergence is to solve the single page website, by switching the browser address path, to match the corresponding page components. To understand this process, let’s look at an ugly picture:

The front-end route matches the corresponding page component according to the change of pathname in the browser address bar. Then, you can create a DOM node by inserting it into the root node

. This gives you the effect of switching pages without refreshing, which also shows that modern frameworks like React, Vue, and Angular have their own lifecycle when creating page components because there is no refreshing.

The principle of

The two most popular front-end routing plug-ins are vue-router and React-router, but their logic is the same.

By analyzing the implementation principle of hash pattern and historical pattern, let everyone have a deeper understanding of the principle of front-end routing.

Hash pattern

The browser gives us a native listener event called Hashchange, which listens for the following changes:

  • Click on theaTAB, changed the browser address
  • The forward and backward behavior of the browser
  • throughwindow.locationMethod to change the browser address

Next, we take advantage of these features to implement a simple hash routing: run online

<! DOCTYPEhtml>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>Hash pattern</title>
</head>
  <body>
    <div>
      <ul>
        <li><a href="#/page1">page1</a></li>
        <li><a href="#/page2">page2</a></li>
      </ul>
      <! -- where to render the corresponding component -->
      <div id="route-view"></div>
    </div>
  <script type="text/javascript">
    // The first time the hashChange listener is loaded, the event is not executed
    // DOMContentLoaded is triggered when the browser DOM has been loaded
    window.addEventListener('DOMContentLoaded', Load)
    window.addEventListener('hashchange', HashChange)
    // Display the node of the page component
    var routeView = null
    function Load() {
      routeView = document.getElementById('route-view')
      HashChange()
    }
    function HashChange() {
      // Each time the hashChange event is triggered, the hash value of the current browser address is obtained from location.hash
      // Display different content according to different paths
      switch(location.hash) {
      case '#/page1':
        routeView.innerHTML = 'page1'
        return
      case '#/page2':
        routeView.innerHTML = 'page2'
        return
      default:
        routeView.innerHTML = 'page1'
        return}}</script>
  </body>
</html>
Copy the code

Of course, this is a very simple implementation, the real hash mode, but also to consider a lot of complex cases, you are interested to see the source code.

The browser display is as follows:

Historical pattern

The History mode is a little more complicated than the hash mode because the history mode relies on the native event popstate. Here is the explanation from MDN:

Fact: pushState and replaceState are both new HTML5 apis that are powerful enough to change the browser address without refreshing the page. This is an important way to change the address bar without refreshing the page.

Click events that include the A tag are also not monitored by popstate. We need to find a way to solve this problem in order to implement the History mode.

** Solution: ** We can use pushState to change the location. Pathname attribute of the browser by iterating through all the a tags on the page, preventing the default event of the a tag, adding a callback function to the click event, and getting the href value of the a tag in the callback. Then manually execute the callback function of the PopState event to match the corresponding route. The logic may be a little leniant, but let’s explain it in code: Online addresses

<! DOCTYPEhtml>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>The History mode</title>
</head>
<body>
  <div>
    <ul>
      <li><a href="/page1">page1</a></li>
      <li><a href="/page2">page2</a></li>
    </ul>
    <div id="route-view"></div>
  </div>
  <script type="text/javascript">
    window.addEventListener('DOMContentLoaded', Load)
    window.addEventListener('popstate', PopChange)
    var routeView = null
    function Load() {
      routeView = document.getElementById('route-view')
      // By default, the popState callback is executed once to match the page component
      PopChange()
      // Get all a tag nodes with href attribute
      var aList = document.querySelectorAll('a[href]')
      // Iterate over the a tag node array, blocking the default event and adding the click event callback function
      aList.forEach(aNode= > aNode.addEventListener('click'.function(e) {
        e.preventDefault() // Block the default event for the a tag
        var href = aNode.getAttribute('href')
        // Manually modify the browser address bar
        history.pushState(null.' ', href)
        // Modify the address bar manually with history.pushState.
        // Popstate does not listen for changes in the address bar, so you need to manually execute the PopChange callback function here
        PopChange()
      }))
    }
    function PopChange() {
      console.log('location', location)
      switch(location.pathname) {
      case '/page1':
        routeView.innerHTML = 'page1'
        return
      case '/page2':
        routeView.innerHTML = 'page2'
        return
      default:
        routeView.innerHTML = 'page1'
        return}}</script>
</body>
</html>
Copy the code

Note here that you cannot open the static file directly in the browser, you need to browse the url through the Web service, starting port.

conclusion

This article focuses on front-end routing. If you can read it completely and explain how it is implemented, I think you will have a new understanding of modern front-end frameworks. No new understanding of the students, come to Hangzhou to hit me, I do not fight back.