HTML5 history pushState/replaceState實例


---恢復內容開始---

在移動端,越來越傾向於頁面內跳轉,而頁面內跳轉就需要用到history的管理,html5的history是一種解決方案。

在沒有history ap之前,我們經常使用散列值來改變頁面內容,特別是那些對頁面特別重要的內容。因為沒有刷新,所以對於單頁面應用,改變其URL是不可能的。此外,當你改變URL的散列值,它對瀏覽器的歷史記錄沒有任何影響。通過增加location.hash,並用onhashchange來達到目的。

現在對於HTML 5的History API來說,這些都是可以輕易實現的,但是由於單頁面應用沒必要使用散列值,它可能需要額外的開發腳本。它也允許我們用一種對SEO友好的方式建立新應用。

使用history

HTML 5提供了兩個新方法:pushstate跟replaceState,兩個方法參數一樣

params { 

  state:存儲JSON字符串,可以用在popstate事件中,可以通過locaton.state獲取。

  title:現在大多數瀏覽器不支持或者忽略這個參數,最好用null代替

  url:任意有效的URL,用於更新瀏覽器的地址欄,並不在乎URL是否已經存在地址列表中。更重要的是,它不會重新加載頁面。

}

兩個方法的主要區別就是:pushState()是在history棧中添加一個新的條目,replaceState()是替換當前的記錄值。用pushState的時候會產生一條新的history,replaceState則不會產生。

當我們使用pushState()和replaceState()進行處理時或者點擊瀏覽器的前進后退的時候,popstate事件會被觸發,通過監聽popstate事件可以達到一系列功能。

瀏覽器支持

history在某些瀏覽器上支持還不是特別好,可以引用這個實現兼容的js

https://github.com/browserstate/history.js

案例DEMO

通過點擊頁面的導航,實現頁面內跳轉,根據popstate監聽URL的改變顯示不同的頁面.

這種路由方式還需要服務器端的支持,不然刷新頁面會出現404

如果入口是index,apache可以在根目錄下建個.htaccess文件,配置如下,

RewriteEngine On

RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]

如果你用的ngnix,配置如下

server {
  ...
  location / {
    try_files $uri /index.html;
  }
}

index.html

<!DOCTYPE html>
<html>
    <head>
        <title>History API</title>
        <meta charset="utf-8" />
    </head>
    <body>
        <ul id="menu">
            <li><a href="/home">首頁</a></li>
            <li><a href="/about">關於我們</a></li>
            <li><a href="/blog">博客</a></li>
            <li><a href="/photos">相冊</a></li>
        </ul>
        <button id="back">Back</button>
        <button id="forward">Forward</button>
        <div>
            Action: <span id="action"></span><br/>
            Url: <span id="url"></span><br/>
            Description: <span id="description"></span>
        </div>
    </body>
</html>

js代碼

        document.addEventListener('DOMContentLoaded', function(){
            var act, historyState;
            var menu = document.querySelectorAll('li a');

            historyState = {
                home : {
                    description : "我是首頁------Index Page"
                },
                about : {
                    description : "關於我們------About Page"
                },
                blog : {
                    description : "博客頁面------Blog Page"
                },
                photos : {
                    description : "相冊頁面------Photos Page"
                }        
            };

            for( let i =0; i < menu.length; i++ ) {
                menu[i].addEventListener('click', function(e){
                    e.preventDefault();
                    var hash = menu[i].getAttribute('href');
                    var key = hash.replace('/','');
                    act = "點擊導航";

                    historyState[key].url = key;

                    //history.pushState(historyState[key], null, hash);    
                    history.replaceState(historyState[key], null, hash);
                    setStateInfo( historyState[key] );

                },false);
            } 


            window.addEventListener('popstate', function(event){
                var state = history.state || event.state || window.event.state;

                if( state) setStateInfo(state);

            },false);

            document.querySelector("#back").addEventListener('click', function(){
                act = "點擊后退按鈕";
                history.back();
            }, false);

            document.querySelector("#forward").addEventListener('click', function(){
                act = "點擊前進按鈕";
                history.go(1);
            });

            function setStateInfo( state ){
                //ajax處理不同的數據
                document.querySelector('#action').innerHTML = act;
                document.querySelector("#url").innerHTML = state.url;
                document.querySelector('#description').innerHTML = state.description;
            }

            //第一次加載進來的時候
            var path = location.pathname;
            var arr = path.split('/');
            var index = arr[arr.length - 1] || 'home'
            
            act = "刷新頁面";
            historyState[index].url =  index;
            setStateInfo(historyState[index]);
            //history.pushState(historyState[index], null, '/home')
            history.replaceState(historyState[index], null, hash);
        },false);   

 通過切換就可以達到頁面跳轉和ajax刷新的效果,而不再出現hash散列值

 

---恢復內容結束---


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM