React learning routing HashRouter and BrowserRouter

There are two ways to implement React routing:

  • HashRouter: Use hash to implement route switching
  • BrowserRouter: Use h5 Api to implement route switching

1.1 HashRouter

Using hash to realize route switching

<body>
    <div id="root"></div>
    <a href="#/a">去/a</a>
    <a href="#/b">去/b</a>
  </body>
  <script>
    let root = document.getElementById('root')
    window.addEventListener('hashchange',(event) =>{
      let hash = window.location.hash
      root.innerHTML = hash
    })
  </script>

Simulate click to switch the page. When the hash value in the browser changes, an event called hashchange will be triggered . This function has a callback that can get the current hash value through window.location.hash

 

 

 1.2 BrowserRouter (browser routing)

The use of h5 Api to achieve routing switching is mainly based on the history object.

  • The history object provides a history interface for operating browser sessions.
  • The historylength attribute declares the number of elements in the browser history list.
  • to pushState , the H5 introduced history.pushState () and History. replaceState () method, respectively can add and modify history entries, these methods typically used in conjunction with window.onpopstate
  • onpopstate , window.onpopstate is the event handler for the popstate event on the window object
setTimeout (() => {
       // pushState will not trigger the event 
      window.history.pushState ({page: 1}, 'page1', '/ page1' ) 
    }, 1000 ) 
    setTimeout (() => {
       // pushState does not Will trigger the event 
      window.history.pushState ({page: 2}, 'page2', '/ page2' ) 
    }, 2000 ) 
    setTimeout (() => {
       // pushState will not trigger the event 
      window.history.pushState ({page : 3}, 'page3', '/ page3' ) 
    }, 3000 )
     // popstate 
    setTimeout (() => is triggered when going back {
      //go (-1) back one, it will trigger popstate event 
      window.history.go (-1 ) 
    }, 4000)

The current path can be stored in the history container through window.history.pushState. This container structure is similar to the stack, which is first in first out. Of course, it can also go back to the previous path through this method of window.history.go. This method will trigger a popstate Event, through this event we can do some operations, such as adding content to the page, etc .:

// This event will be triggered when go (-1), you can change the document content when triggered 
    window.onpopstate = function (event) { 
      console.log (event) 
      root.innerHTML = window.location.pathname 
    }

 

 The history object has events when it rolls back, but it does not trigger events during pushstate. If we want to do some operations ourselves, we need to rewrite an onpushState event so that we can perform page operations.

let root = document.getElementById('root')
    window.onpushstate = function(state,title,url) {
      root.innerHTML = url
    }

    ;(function (history) {
      //1.缓存原生的pushState方法
      let pushState = history.pushState 
      //2.改写pushState方法
      history.pushState = function(state,title,url) {
        
        //3.自定义改写后的事件名为onpushstate
        if(typeof window.onpushstate === 'function') {
          window.onpushstate(state,title,url)
        }
        //4.调用原生方法并且执行
        pushState.call(history,state,title,url)
      }
    })(window.history)

看过vue源码的同学肯定知道vue里面对数组的响应式处理就是通过改写数组的那7个方法实现的。我们这里也一样,拦截了原生的方法,对原生方法进行了缓存,然后再改写原生方法,最后再执行,就这么简单。

完整版:

<body>
    <div id="root"></div>
  </body>
  <script>
    let root = document.getElementById('root')
    window.onpushstate = function(state,title,url) {
      root.innerHTML = url
    }

    ;(function (history) {
      //1.缓存原生的pushState方法
      let pushState = history.pushState 
      //2.改写pushState方法
      history.pushState = function(state,title,url) {
        
        //3.自定义改写后的事件名为onpushstate
        if(typeof window.onpushstate === 'function') {
          window.onpushstate(state,title,url)
        }
        //4.调用原生方法并且执行
        pushState.call(history,state,title,url)
      }
    })(window.history)
    //这个事件会在go(-1)的时候触发,可以在触发的时候改变文档内容
    window.onpopstate = function(event){
      console.log(event)
      root.innerHTML = window.location.pathname
    }
    // window.history 这是浏览器原生提供的对象,通过它来操作会话容器
    setTimeout( () => {
      //pushState不会触发事件
      window.history.pushState({page: 1},'page1','/page1')
    },1000)
    setTimeout( () => {
      //pushState不会触发事件
      window.history.pushState({page: 2},'page2','/page2')
    },2000)
    setTimeout( () => {
      //pushState不会触发事件
      window.history.pushState({page: 3},'page3','/page3')
    },3000)
    //后退的时候触发popstate
    setTimeout( () => {
      //go(-1)后退一个,会触发popstate事件
      window.history.go(-1)
    },4000)

  </script>

下一节写一个自己的路由库!

 

Guess you like

Origin www.cnblogs.com/lyt0207/p/12716369.html