返回鍵 pushState history popstate

停用瀏覽器返回按鈕 (Disable browser back button )

李建毅 (Joe Lee) 2020/03/11 16:50:10
6978

一. 前言

有些網頁功能需要限制返回功能,以前做不到現在有了 popstatepushStat 而可得到解決。



二. 基礎認識

  1. popstate

視窗上 popstate 事件的事件處理器。

 

       在同一文件的當前歷史紀錄變動時,如果其變動介於兩個歷史紀錄間,popstate 就會被呼叫。如果當前的歷史紀錄是藉由呼叫 history.pushState() 建立,或曾被 history.replaceState() 修改過,popstate 事件的 state 屬性,將包含一份歷史紀錄的 state 物件。

 

請注意:直接呼叫 history.pushState()history.replaceState() 不會驅動 popstate 事件。popstate 事件只會被瀏覽器的行為驅動,例如點擊上一頁按鈕(或透過 JavaScript 呼叫 history.back())。且此事件只會在用戶於同文件的兩個歷史紀錄間瀏覽時作動。

 

在頁面載入時,不同瀏覽器具有不同的 popstate 行為。Chrome 與 Safari 會在頁面載入時觸發 popstate 事件,但 Firefox 則不會。

 

window.addEventListener('popstate',function(event){
        history.pushState(null, document.title, location.href);
});

or

window.onpopstate = function(event) {
  alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
};



  1. history

DOM window 物件透過 history 物件,提供了進入瀏覽歷史的方式。

他透過一些方便的屬性與方法,讓你可以在歷史紀錄中往上一步或往下一步移動,並且讓你——從 HTML5 開始——能操作歷史紀錄堆疊(history stack)的內容。



前往後歷史紀錄

往前往後歷史紀錄可以用 back(), forward(), 和 go() 的方法。

//上一頁
window.history.back();

//下一頁
window.history.forward();

//移動到特定的歷史紀錄
window.history.go(-1); //上一頁
window.history.go(1);  //下一頁



加入修改歷史紀錄

HTML5 加入了 history.pushState()history.replaceState() 方法,讓你可以加入或修改歷史紀錄。這些方法都可以跟 window.onpopstate 事件一同應用。

 

使用 history.pushState()後,會改變 XMLHttpRequest 時 HTTP 標頭中 referrer 的值。referrer 會是創造 XMLHttpRequest 物件時的當前視窗文件(this)的 URL。

 

var stateObj = { foo: "bar" };

/**
state object:
是與 pushState() 建立的新瀏覽歷史紀錄有關的一個 JavaScript 物件。
只要使用者到了新的 state ,一個 popstate 的事件就會被觸發,然後該事件的 state 屬性會包含一個複製的歷史紀錄的 state object。

title:
Firefox 目前忽略了這個參數,雖然他以後有可能會採用。
如果以後改變了這個作法,傳送空白的字串應該還會是安全的。另外,你可以傳送一個短的標題來敘述你想要到的 state。

URL:
這個新歷史紀錄的 URL 從這個參數做設定。
**/
history.pushState(stateObj, "page 2", "bar.html");

history.replaceState(stateObj, "page 3", "bar2.html");

 

 

三. 實例說明

      本範例方法,(範例3)利用修改歷史紀錄變更上一頁與本頁相同造成限制返回功能。 Back 按鈕、瀏覽器返回按鈕初期可以正常返回,如執行 Disable 按鈕 Back 按鈕、瀏覽器返回按鈕就會失去作用。以3頁做測試避免返回

 

範例1 (first_page.html 初始頁) 

<main role="main">

        <section class="jumbotron text-center">
            <div class="container">
                <h1 class="jumbotron-heading">First page</h1>
                <p class="lead text-muted">Disable browser back button</p>
                <p>
                    <!--<a href="#" class="btn btn-primary my-2"></a>-->
                    <a onclick="nextpage();" class="btn btn-secondary my-2">second</a>
                </p>
            </div>
        </section>

        <script language="javascript">
            function nextpage() {
                window.location.href = "second_page.html";
            }
        </script>

    </main>

 

 

範例2 (second_page.html 可正常返回頁)

<main role="main">

        <section class="jumbotron text-center">
            <div class="container">
                <h1 class="jumbotron-heading">Second page</h1>
                <p class="lead text-muted">Disable browser back button</p>
                <p>
                    <a onclick="backpage();" class="btn btn-primary my-2">Back</a>
                    <a onclick="nextpage();" class="btn btn-secondary my-2">Third</a>
                </p>
            </div>
        </section>

        <script language="javascript">
            function backpage() {
                window.history.back();
            }
            function nextpage() {
                window.location.href = "third_page.html";
            }
        </script>

    </main>

 

範例3 (third_page.html 實際功能頁)

    <main role="main">

        <section class="jumbotron text-center">
            <div class="container">
                <h1 class="jumbotron-heading">Third page</h1>
                <p class="lead text-muted">Disable browser back button</p>
                <p>
                    <a onclick="backpage();" class="btn btn-primary my-2">Back</a>
                    <a onclick="stoppage();" class="btn btn-danger my-2">Disable</a>
                </p>
            </div>
        </section>

        <script language="javascript">
            function backpage() {
                window.history.back();
            }
            function stoppage() {
                history.pushState(null, document.title, location.href);
            }

            function stopPopstate(event) {
                history.pushState(null, document.title, location.href);
            };

            window.addEventListener('popstate', stopPopstate);

        </script>

    </main>

 

 

四. 參考

https://developer.mozilla.org/zh-TW/docs/Web/API/Window.onpopstate

 

https://developer.mozilla.org/zh-TW/docs/Web/API/History_API

 

李建毅 (Joe Lee)