HTML5——history实现单页面

1. 单页Web应用(single page web application,SPA)

history.back():URL回退一次

history.forward():URL前进一次

history.go(n):URL几次history.back()或几次history.forward(),比如:history.go(2):两次history.forward();history.go(-2):两次history.back();

history.length:length属性,可以查看URL的数量

 

2. HTML5中添加了一些方法,可以显示单页面应用

3. 方法

(1)pushState方法

history.pushState(state, title, url):将这个URL添加到历史记录中

(2)replaceState方法

history.replaceState(state, title, url):将这个URL替换当前的URL

参数:

state:一个状态对象,可以是数据对象,popstate事件触发时,会把该对象传入回调函数中;popstate事件:当历史记录发生改变时,触发该事件。

title:新页面标题,所有浏览器都忽略了该值,该值为填null。

URL:新的网址,必须和该页面处在同一个域下

注意:pushState和replaceState不刷新页面,所以,URL发生了变化,但是内容没有刷新加载,内容没有变化。

如何做?在添加或替换URL的时候,直接拼接一个“?one” “?two”、?three等等。拼接一个URL的标识。

然后在通过ajax改变网页内容,就实现了“单页面应用”

history.pushState(null, null, "?zhuyuzhu"):添加一个历史记录,空对象,空标题,拼接的URL

4. 事件

(1)popstate事件:历史记录发生改变时触发,比如:向前翻,向后翻都会触发该事件

但是:pushState和replaceState两个方法也改变了历史记录,但是不会触发popstate事件

    <script>
          history.pushState({name:"zhu",age:22,sex:"male"}, null, "?zhuyuzhu");
          //监听popstate事件
          window.addEventListener('popstate', function(e){
              console.log(e);
          })
    </script>

注意:state对象的值,每一个URL对应自己的state值。

注意:上面代码中:history.pushState({name:"zhu",age:22,sex:"male"}, null, "?zhuyuzhu");只是将URL和state数据添加进去,要想触发popstate事件,还是要

实现SPA:注意代码中的备注

html部分:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>单页面应用</title>
    <style>
        * {
            padding: 0px;
            margin: 0px;
            font-size: 0px;
        }

        .wrapper {
            position: absolute;
            left: 50%;
            margin-left: -200px;
            width: 400px;
            height: 400px;
            border: 1px solid #000;
        }

        .heard {
            width: 100%;
            display: flex;
        }

        button {
            width: 133px;
            flex-grow: 1;
            height: 50px;
            font-size: 20px;
        }

        .item {
            text-align: center;
            line-height: 350px;
            font-size: 30px;
        }
    </style>
</head>

<body>
    <div class="wrapper">
        <div class="heard">
            <button data='one'>1</button>
            <button data='two'>2</button>
            <button data='three'>3</button>
        </div>
        <div class="content">

            <div class="item">88</div>
        </div>
    </div>
    <script src="./ajax.js"></script>
    <script>
        var heard = document.getElementsByClassName('heard')[0];
        var item = document.getElementsByClassName('item')[0];
        var page = '';
        var oldPage = '';
        function init() {
            history.replaceState({
                newpage: 'one'
            }, null, '?one');
            ajaxFunc('GET', './getData.php', 'page=one', callback, true);
        }
        init();

        function callback(requestData) {
            console.log(requestData);
            item.innerHTML = requestData;
        }
        
        heard.addEventListener('click', function (e) {
            oldPage = page;
            console.log(oldPage);//打印上一个page值
            //获取标签内自定义的属性值
            page = e.target.getAttribute('data');//将点击的标签中的data属性值,赋给page;
            console.log(page);//打印新的page值
            //进行判断,如果新的page值和上一个page值相等,表明用户在连续点击某一个按钮,不触发pushState事件
            if(page !== oldPage){
                history.pushState({
                newpage: page
            }, null, '?' + page);
            ajaxFunc('get', './getData.php', 'page=' + page, callback, true);
            }
        })
        //监听popstate事件
        window.addEventListener('popstate', function (e) {
           console.log(e);
            var newpage = e.state.newpage;
            console.log(newpage);
            ajaxFunc('get', './getData.php', 'page=' + newpage, callback, true);
        })
    </script>
</body>
</html>

js部分:ajax函数

function ajaxFunc(method, url, data, callback, flag) {
    //请求类型、php文件的地址、post类型需要的数据、回调函数、是否异步
    var xhr = null;
    if (window.XMLHttpRequest) {
        //非IE
        xhr = new XMLHttpRequest(); 
    } else {
        //IE
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }
    method = method.toUpperCase();
    if(method == 'GET'){
        xhr.open(method, url+'?'+ data, flag); 
        xhr.send(); 
    }else if(method == 'POST'){
        xhr.open(method, url, flag);
        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        xhr.send(data);
    }
    xhr.onreadystatechange = function () { 
        if (xhr.readyState == 4) { 
            if (xhr.status == 200) {       
                callback(xhr.responseText);
            }
        }
    }
}

php部分:

<?php
header('content-type:text/html;charset="utf-8"');
error_reporting(0);

$page = $_GET['page'];
if($page == 'one'){
    $data = '111';
   
} else if($page == 'two'){
    $data = '222';
    
} else if($page == 'three'){
    $data = '333';
    
}
echo "{$data}";
?>

(2)hashchange事件

当URL中的hash值发生变化时,触发该事件

hash值:URL中# 部分

注意下面例子中,会体现a标签的特性:

(1)锚点;(2)hash值;

注意:给div加滚动条,overflow:auto;包括:overflow-x:auto和overflow-y:auto;

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>test</title>
    <style>
         .left{
             position: absolute;
             left: 50px;
             top: 100px;
             width: 150px;
             height: 200px;
             border: 1px solid black;
             overflow: auto;
         }
         a{
             text-decoration: none;
             display: block;
             width: 100px;
             height: 50px;
             background-color: #f3f3f3;
             line-height: 50px;
             text-align: center;
             margin-top: 10px;
             overflow: auto;
         }
         .right{
             position: absolute;
             top: 70px;
             left: 300px;
             border: 1px solid black;
             width: 400px;
             height: 500px;
             overflow: auto;
         }
         .right div{
             width: 100px;
             height: 100px;
             border: 1px solid black;
             position: absolute;
             left: 10px;
             
         }
         #one{
             top:10px;
         }
         #two{
             top: 520px;
         }
         #three{
             top: 930px;
         }
         #four{
             top: 1340px
         }
         #five{
             top: 1750px;
         }
    </style>
</head>

<body>
        <div class="left">
            <a href="#one">111</a>
            <a href="#two">222</a>
            <a href="#three">333</a>
            <a href="#four">444</a>
            <a href="#five">555</a>
        </div>
        <div class="right">
            <div id="one">1111111</div>
            <div id="two">2222222</div>
            <div id="three">3333333</div>
            <div id="four">44444444</div>
            <div id="five">5555555</div>
        </div>
    <script src="./ajax.js"></script>
    <script>  

        window.addEventListener('hashchange', function(e){
            console.log(111)
        })
    </script>
</body>
</html>

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值