preface

At present, the most popular front-end development is SPA single-page architecture. React, Vue and angluarJS of front-end development are all based on this model. Single page means that there is only one main page. It simulates the effect of multiple pages by dynamically replacing DOM content and changing THE URL address. The function of switching pages is directly completed by the foreground script. SPA can simulate the effects of multi-page applications thanks to the front-end routing mechanism. It can be implemented in two ways

1. HashChange

The basic principle of

Basic routing is achieved by changing the HASH value of the URL (the anchor point) and then triggering the hashChange event of the Window object. The code triggers DOM changes for the corresponding page

The instance

    // HTML 
    <a href="#angluarJS">angluarJs</a>
    <a href="#react">react</a>
    <a href="#vue">vue</a>
    <div id="content"></div>

    // JS
    location.hash = 'angluarJs';
    let c = document.querySelector('#content');
    window.onhashchange = function (opt) {
        c.innerHTML = 'Current page is' + location.hash;
    }
Copy the code

2. History API

In HTML4, the window.history object was already supported to control the jump of page history. Common methods include:

  1. history.forward(); Equivalent to the advance of the browser
  2. history.back(); Equivalent to a browser back
  3. history.go(n); Jump n steps in history, refresh the page when n=0, back one page when n=1

In HTML5, window.history has been extended again with new apis:

  1. history.pushState(); Appends a record to history
  2. history.replaceState(); Replaces the current page’s information in history
  3. history.state; A property, state information for the current page
  4. window.onpopstate(); An event that is triggered when the browser is clicked forward or backward

The basic principle of

When a browser visits a page, the current address is pushed into the history stack. When history.pushState() is called to push a new state into the history stack, the pointer at the top of the history stack points to the new state, which is equivalent to pretending to have changed the URL and then jump. The window. onPopState event is raised when the browser’s forward or back is clicked or JS triggers forward or back.

The instance

// HTML <h1> <ul id="list">
        <li>angularJs</li>
        <li>react</li>
        <li>vue</li>
    </ul>
    <div id="content"></div>

    // JS
    document.querySelector('#list').addEventListener('click'.function (e) {
        if(e.target.tagName === 'LI') {
            let content = e.target.innerHTML;
            let newState = {
                url: location.origin + '/' + content,
                title: document.title,
                state: content
            };
            // (data,title,url)
            window.history.pushState(newState,' '.'/'+content); urlChange(newState); }},false); // When the browser moves forward or backward, window. onpopState = is triggeredfunction(e) {// pushState or repalceState pass urlChange(e.state); };let c = document.querySelector('#content');
    function urlChange(state) {
        if(state) {
            c.innerHTML = 'Current page is' + state.state;
        }else {
            c.innerHTML = 'Current page is angularJs'; }}Copy the code

Two ways to compare

contrast Hash routing The History of API routing
Naming restrictions Usually only in onedocumentMake changes The URL address can be customized as long as it belongs to the same domain name
URL Change Will change You can change, you can not change
State of preservation No built-in methods Pages can be pushed onto the information stack with custom information
practical Available for direct use Requires the server to modify the code to implement
compatibility IE8 above Ie 10 or more

application

I’ve wrapped a plugin to implement simple front-end routing, support hash and history modes, and the code is here, using the following:

Hash pattern

// HTML <p> <ul> <li><a YM-link ="#angularJs" >angular</a></li>
        <li><a ym-link="#vue">vue</a></li>
        <li><a ym-link="#react">react</a></li>
    </ul>
    <div id="ymapp"Here is the template container </div> // JS$YMRouter.init({
        mode: 'hash',
        list: {
            '#angularJs': 'this is the page of angularJs'.'#vue': 'this is the page of vue'.'#react': 'this is the page of react'}});Copy the code

The history mode

// HTML <p> <ul> li><a ym-link="/angularJs" >angular</a></li>
        <li><a ym-link="/vue">vue</a></li>
        <li><a ym-link="/react">react</a></li>
    </ul>
    <div id="ymapp"Here is the template container </div> // JS$YMRouter.init({
        mode: 'hash',
        list: {
            '/angularJs': 'this is the page of angularJs'.'/vue': 'this is the page of vue'.'/react': 'this is the page of react'}});Copy the code

The problem

  1. The server must perform routing processing. No matter which page the front end visits, the front end returns to the home page; otherwise, 404 is displayed when the page is refreshed
  2. History mode can also leave the URL unchanged, but this plugin does not do this