Hash pattern

The hash is the # and the character after the end of the URL. Changes in the hash value do not cause the browser to send a request to the server, and changes in the hash value trigger the onHashChange event.

Features of Hash:

The hash, while present in the URL, is not included in the HTTP request and has no impact on the back end, so changing the hash does not reload the page. Hash was originally used for page positioning, but if it was used for routing, the anchor function would not work. Hash mode is also called front-end routing because changing the hash value does not send requests to the back end

Window.location. hash='qq'// Set the url hash, #qq' var hash = window.location.hash //'#qq' window.adDeventListener ('hashchange',function(){// Clicking browser forward or back will trigger})Copy the code

The history mode

History does not appear with a # sign in the URL and begins with a /, as HTTP does, so the page is reloaded when history changes.

Route history provides two APLis (pushState() and replaceState() to change pathame without refreshing the page)– these two methods accept three arguments; StateObj, title, url

History mode can not only put parameters in urls, but also store data in a specific object.

History can also change the URL directly but refresh the page wido.location. pathName ='/first'   // Set the URL's history value to '/first'
    
var history = window.location.history //'/first'
    
Copy the code
history API
  1. Switching history states, including back() back, foward() forward, and go() jump, will move forward and backward in the browsing history, and if it goes beyond that, the called method will have no effect
history.back(); / Back up a history. forward();// Advance onceHistory. The go ();// Refresh the current page
    history.go(-2);// Back up twice
    history.go(2);// Proceed twice
Copy the code
Note: When you move to a previously visited page, the page is usually loaded from the browser cache, rather than re-asking the server to send a new page.Copy the code
  1. You can modify the historical status of pushState or replaceState
    window.history.puahState(stateObj,title,url);
    //state: Data that needs to be saved. This data can be retrieved in event.state when the popState event is triggered
    //title: title, now basically useless, usually pass null or ""
    //url: Set the url of the new history. The origin of the new URL must be the same as the origin of the current URL. Otherwise, an error will be generated and the browser address bar will display the new URLThe instance1If the current url is www.com/first, use the history.pushstate () method to add a new record to the browsing historywindow.history.pushState({first;1},null.'second'); The address bar of the browser will immediately display as www.com/second, but it will not jump to the second page or even check whether second exists. When you visit a new address (Baidu.com), the url of the page will display second when you roll back once, and the first instance will be displayed when you roll back again2If the current URL is www.com/a/window.history.pushState(null.null.'./qq/'The URL becomes: www.com/a/qq/// The preceding route must end with /; otherwise, the route will not be spliced
Copy the code
    window.history.replaceState(stateObj,title,url);
    // Basically the same as pushState, except that replaceState() modifies the current history and pushState() creates a new historyThe instance1If the current page is: www.com history.pushState(null.null.'/html.1');
    //www.com/html.1
    history.pushState(null.null.'/html.2');
    //www.com/html.2
    history.replaceState(null.null.'html.3');
    //www.com/html.3 replaceState replaces that pathname
    
    history.back();  // Back up once
    //www.com/html.1
    history.back();  // Back up once
    //www.com
    history.go(2)   // Proceed twice
    //www.com/html.3
Copy the code
  1. Popstate event

The popState event is triggered when the browser history object changes, but the pushState() and replaceState() methods do not. The popState event is triggered only when the user clicks the browser back and forward buttons. Or if the history.back(), history.forward(), or history.go() methods are used. This event applies only to the same document and will not be triggered if a switch in browsing history results in a different document being loaded.

    window.addEventListener('popstate'.cunction(){
       console.log(111);
    })
    
    history.back():   / / 111
Copy the code

Listen for history changes

Most of the time, we want to change the URL without the browser making the request, but in History, calls to pushState() and replaceState() change the URL without refreshing the page, but without listening for their methods, we can’t listen for changes in the route to execute the corresponding JS.

History does not have onHashchange listeners like Hash, so we can write our own listener event, complete a subscription-publish pattern, and then override history.puahState and history.replaceState to add message notifications.

    class Store {            / / subscribe to the pool
  constructor(name) {
    this.store = []     // The collection of objects subscribed to under this event
  }
  bind() {             // Add subscribers
    Store.watch.add(this)}dispatch() {        // Notify subscribers of changes
    this.store.forEach((item) = > {
      if (typeof item.update === 'function') {   // Determine whether the corresponding event in the store object is a method
        item.update.apply(item)     // Trigger the subscriber update function
      }
    })
  }
}
Store.watch = null;         // Create an empty subscriber

class Watch {
  constructor(name, fn) {
    this.name = name;      // The name of the subscription message
    this.callBack = fn;    // The callback function executed by the subscriber when the subscription message changes
  }
  add(dep) {              // Put the subscriber into the subscription pool
    dep.store.push(this);
  }
  update() {              // Update the subscriber method
    var cb = this.callBack;// Assign so as not to change the this called within the function
    cb(this.name); }}// Override pushState and replaceState methods
var addHistoryMethod = (function () {   // Returns the result of a self-executing function, or if it is a function
  var historyStore = new Store();
  return function (name) {              // Pass a name through historyMethod()
    if (name === 'historychange') {     // Determine what method is called and return a function
      return function (name, fn) {
        var event = new Watch(name, fn) // give the Watch instance to event
        Store.watch = event;            // Give the instance to Store. Watch to call the add method in bind
        historyStore.bind();
        Store.watch = null;            // empty for use by the next subscriber}}else if (name === 'pushState' || name === 'replaceState') {
      var method = window.history[name]; //history.name
      return function () {
        method.apply(window.history, arguments);// History indicates that this is history, and arguments get the arguments passed inhistoryStore.dispatch(); }}}} ())// Set the listening style
window.addHistoryListener = addHistoryMethod('historychange');
window.history.pushState = addHistoryMethod('pushState');
window.history.replaceState = addHistoryMethod('replaceState');
Copy the code

Call listening History

    window.history.pushState(null.null.'/second')
    window.addHistoryListener('history'.function() {
        console.log('History has changed')})Copy the code