使用hash和history实现前端历史状态切换,触发事件驱动函数来完成部分数据的加载(使用hash和history实现前端路由切换,含完整源码+注释)

Posted 勇敢*牛牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用hash和history实现前端历史状态切换,触发事件驱动函数来完成部分数据的加载(使用hash和history实现前端路由切换,含完整源码+注释)相关的知识,希望对你有一定的参考价值。

根据loaction下的这个hash值变化,触发事件驱动函数来完成部分数据的加载

根据loaction下的这个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>
    <style>
        ul
            list-style: none;
            margin: 0;
            padding: 0;
        
        li
            float: left;
            width: 120px;
            height: 30px;
            text-align: center;
            line-height: 30px;
            border: 1px solid #000;
            border-left: none;
        
        li:first-child
        
            border-left: 1px solid #000;
        
        .clear::after
        
            content: "";
            clear: both;
            visibility: hidden;
            display: block;
            height: 0;
            overflow: hidden;
        
        div
            width: 1000px;
            height: 400px;
            border: 1px solid #000;
            margin-top: 10px;
        
        a
            text-decoration: none;
            color: #000;
            display: block;
            width: 100%;
            height: 100%;
        

        
    </style>
</head>
<body>
    <ul class="clear">
        <li id="vegetable"><a href="#vegetable">蔬菜</a></li>
        <li id="fruit"><a href="#fruit">水果</a></li>
        <li id="meat"><a href="#meat">禽肉</a></li>
        <li id="oils"><a href="#oils">粮油</a></li>
    </ul>
    <div id="div1"></div>
    <script>
        var data=
            vegetable:["大白菜","青菜","白菜","茭白","莲花白","胡萝卜"],
            fruit:["苹果","香蕉","菠萝","鸭梨","西瓜","荔枝"],
            meat:["鸭肉","牛肉","猪肉","羊肉","鸡肉","鱼肉"],
            oils:["绿豆","大米","花生油","菜籽油","橄榄油","大豆"]
        
        // 初始化
        init();
        var div,prev;
        function init()
            //  哈希被修改时,触发事件函数
            // 多次修改多次重新触发执行函数
            window.onhashchange = hashChangeHandler;
            div = document.getElementById('div1');
            // 判断地址栏有没有哈希地址
            if(!location.href.includes('#'))
                location.href += "#vegetable"
            console.log(location.hash.slice(1));
            // changePrev(document.getElementById(location.hash.slice(1)));
            // hashChangeHandler();

            
            
        
        function hashChangeHandler()
            // 每次触发时可以获取哈希值#……
            // console.log(location.hash);
            var temp = location.hash.slice(1)
            var arr = data[location.hash.slice(1)]
            // console.log(arr);
            // console.log(location.hash.slice(1));
            div.innerHTML = arr.join(',')
            // 这里使用和上面使用的效果一样
            changePrev(document.getElementById(location.hash.slice(1)));
        

        function changePrev(elem)
            if(prev)
                prev.style.backgroundColor= "white"
            
            prev = elem;
            // 然后给这个标签加上样式
            prev.style.backgroundColor = 'pink'
        
    </script>
</body>
</html>

history历史状态记录

根据history.state记录,更新数据渲染

<!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>
     <style>
        ul
            list-style: none;
            margin: 0;
            padding: 0;
        
        li
            float: left;
            width: 120px;
            height: 30px;
            text-align: center;
            line-height: 30px;
            border: 1px solid #000;
            border-left: none;
        
        li:first-child
        
            border-left: 1px solid #000;
        
        .clear::after
        
            content: "";
            clear: both;
            visibility: hidden;
            display: block;
            height: 0;
            overflow: hidden;
        
        div
            width: 1000px;
            height: 400px;
            border: 1px solid #000;
            margin-top: 10px;
        
        
    </style>
</head>
<body>
    <ul class="clear">
        <li id="vegetable">蔬菜</li>
        <li id="fruit">水果</li>
        <li id="meat">禽肉</li>
        <li id="oils">粮油</li>
    </ul>
    <div id="div1"></div>
<script>
        var data=
            vegetable:["大白菜","青菜","白菜","茭白","莲花白","胡萝卜"],
            fruit:["苹果","香蕉","菠萝","鸭梨","西瓜","荔枝"],
            meat:["鸭肉","牛肉","猪肉","羊肉","鸡肉","鱼肉"],
            oils:["绿豆","大米","花生油","菜籽油","橄榄油","大豆"]
        

        var lis,div,prev;

        init();
        function init()
            lis = Array.from(document.getElementsByTagName('li'))
            // 添加一个history历史监测
            window.onpopstate = popstateHandler;

            div = document.getElementById('div1')
            // 给每一个li添加点击事件
            for (let index = 0; index < lis.length; index++) 
                lis[index].onclick = clickHandler;
                
            
            // 如果第一次历史状态为空,那么给所谓默认的第一个历史状态添加一个历史状态
            var li = history.state? document.getElementById(history.state):lis[0]
            history.replaceState(li.id,li.id)
            resetData(li)
            
            // resetData(lis[0])
            // 将历史记录上的第一次null换为lis[0].id,
            // history.replaceState(lis[0].id,lis[0].id)
        
        function clickHandler()
            history.pushState(this.id,this.id)
            resetData(this)

        
        function resetData(elem)
            div.innerHTML = data[elem.id]
            changePrev(elem)

        
        function changePrev(elem)
            if(prev)
                prev.style.backgroundColor = 'white'
            
            prev = elem;
            prev.style.backgroundColor = 'pink'
        

        function popstateHandler()
            resetData(document.getElementById(history.state))
            // console.log(history.state);
        
    </script>
</body>
</html>

以上是关于使用hash和history实现前端历史状态切换,触发事件驱动函数来完成部分数据的加载(使用hash和history实现前端路由切换,含完整源码+注释)的主要内容,如果未能解决你的问题,请参考以下文章

关于hash和history的区别和使用

前端路由实现(history)

前端路由的实现 —— History的pushState和replaceState用法

hash和history 的区别仅仅是#吗?

hash与history的区别

Vue-两种路由模式 hash 和 history