Front-end routing? How to manually implement front-end routing

I signed up for the first challenge of the Golden Stone Project - Divide the 100,000 prize pool, this is my third article, click to view the details of the event

The front-end did not have the concept of routing at the beginning, because at the earliest, when the front-end was responsible for cutting pictures, an html file path corresponds to a page, there is no concept of routing, only the concept of page and path. And with the development of the front-end, the front-end is no longer just a role of a simple figure-cutting boy, and the concept of routing is also introduced.

What is front-end routing?

When it comes to what is front-end routing, let's take a chestnut first.

Here, we are on the homepage of Nuggets, the path is: juejin.cn/recommended

image.png

Then we click on the boiling point:

The path becomes: juejin.cn/pins

image.png

What we can see here is that only the last and last part of the path has changed, and the previous path has not changed.

What does this mean? This is actually a single-page page. There is only one page. Clicking to jump is just by changing the path to render different page effects. However, it is worth mentioning that the page is not refreshed. There is a process volume.

That is, before and after you click the boiling point on the home page, you can see that the page refresh button is not refreshed.

L{84)19$6KR05A7Z7BPMWJ4.png

Summary: Front-end routing is to describe the mapping relationship between url and page ui, one-way mapping.

What should be done to implement routing?

1. How to change the url without causing the page to refresh

2. How to detect that the url has changed

How to implement front-end routing

hash

Hash is also called hash. It should be noted that if the hash value part of the browser url is changed, the page will not be refreshed.

Here, we have written two a tags, the paths are /homeand respectively /about, then click the hyperlinks of these two a tags, our page will jump to the next page, that is, a multi-page application.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul>
        <li>
            <a href="/home">首页</a>
        </li>
        <li>
            <a href="/about">关于</a>
        </li>
    </ul>

    <!-- 渲染对应的UI -->
    <div id="routerView"></div>
</body>
</html>
复制代码

So, how to implement hash routing?

首先,我们只要把a标签的路径改为#/home#/about,hash路径都要加上一个#前缀,浏览器会自动识别这是hash路径,从而达到路径发生改变,但页面并没有进行刷新跳转,仍旧处于原本这个页面。

<body>
    <ul>
        <li>
            <a href="#/home">首页</a>
        </li>
        <li>
            <a href="#/about">关于</a>
        </li>
    </ul>
</body>
复制代码

可浏览器识别了路径的hash值发生了改变,页面也并没有什么其它的东西渲染出来啊?这就是我们需要解决的第二个问题了,怎样检测监听页面url的改变,我们只需要检测到页面url的改变,且获取改变的那一段页面url,来判断那一段url应该在页面上渲染什么。

那么,怎么检测页面url发生改变呢?

window.addEventListener('hashchange',onHashChange)
复制代码

JS自带一个有关于window事件的监听,第一个参数为hashchange,即监听页面url的hash值改变,第二个参数为一个函数,这里我们为了好看一点,这里放上函数名onHashChange

只要页面的url里hash值部分发生改变,那么就会调用onHashChange函数。

再通过location.hash来获取页面改变的hash值部分在函数里面来决定应该渲染哪一部分页面。

完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul>
        <li>
            <a href="#/home">首页</a>
        </li>
        <li>
            <a href="#/about">关于</a>
        </li>
    </ul>

    <!-- 渲染对应的UI -->
    <div id="routerView"></div>

    <script>
        let routerView = document.getElementById('routerView')
        window.addEventListener('hashchange',onHashChange)

        //控制渲染对应的ui
        function onHashChange(){
            switch(location.hash){
                case '#/home':routerView.innerHTML='首页'
                braek;
                case '#/about':routerView.innerHTML='关于'
                break;
                default:return
            }
        }
    </script>
</body>
</html>
复制代码

效果如图:

~N1}ADKSZTBN1Q28O8%`R`0.png 73M13IR(_$9FWRE2}NTZH8B.png SR))O@1H[YS~O0IUEKYG6N7.png

hash实现路由非常简便,但是有一个小弊端,就是路径不美观,每一段路径都会加一个#号,而路径我们一般都是/去分割,多加一个#不太美观,所以我们通常用history方法实现路由用的更多。

history

history是HTML5提供的一个对象方法。

而我们要实现history路由之前,我们应该知道这么三种方法:

  1. pushState //增加url,且不会引起页面变化
  2. replaceState //修改url 并且不会引起页面刷新的
  3. popState //监听url变化

在用history方法之前,我们需要先监听a标签的点击事件,然后阻止a标签自带的跳转,这里我们使用preventDefault()方法。

a.getAttribute('href')获取a标签里的href路径,用作于history的history.pushState(null,'',a.getAttribute('href'))里,添加改变路径。

Then call PoPStatethe function to decide which part of the function to render

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul>
        <li>
            <a href="/home">首页</a>
        </li>
        <li>
            <a href="/about">关于</a>
        </li>
    </ul>

    <!-- 渲染对应的UI -->
    <div id="routerView"></div>
    <script>
        let routerView = document.getElementById('routerView')

        window.addEventListener('DOMContentLoaded',onLoad)    //页面第一次加载就进行默认选中渲染内容
        // window.addEventListener('popstate',PoPState)          //浏览器的前进后退能匹配
        function onLoad(){
            PoPState()
            let links = document.querySelectorAll('li a[href]')
            links.forEach(a=>{
                a.addEventListener('click',(e)=>{
                    e.preventDefault();      //阻止a标签的href标签
                    
                    history.pushState(null,'',a.getAttribute('href'))
                    PoPState()
                })
            })
        }
        onLoad()
        function PoPState(){
            switch(location.pathname){
                case '/home':
                    routerView.innerHTML = '<h2>home page</h2>'
                    return
                case '/about':
                    routerView.innerHTML = '<h2>about page</h2>'
                    return
                default:
                    return
            }
        }
    </script>
</body>
</html>
复制代码

The effect is as follows:

image.png image.png image.png

In general, the routing effect is achieved by changing the page url without refreshing the page, and then judging the path to select different components to render the page.

Guess you like

Origin juejin.im/post/7143064688661069854