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>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章