History API

history は呼び出されたページの記録です。
History API を使って「どこでもドアー」のように、リンク先(戻り先)を自由に選択します。
また、戻りボタンを利かなくする方法にも触れてみます。
実行環境(Windows, Unix, Microsoft Edge, Google Chrome, etc)によって実行できない場合があります。

  1. page_a.html, page_b.html, page_c.html のページを作成します。
    page_b.html, page_c.html はタイトル表示が異なるだけです。
    <html>
    <head>
    <meta http-equiv="Content-Script-Type" content="text/javascript" charset="utf-8">
    <title>Page A</title>
    
    <script type="text/javascript">
      function Call(page)
      {
        location.href = page;
      }
    </script>
    </head>
    
    <body>
    <h2>Page A</h2>
    <form name="Ctrl">
        <input type="button" value="Page A を呼び出す" onClick="Call('page_a.html')"><br><br>
        <input type="button" value="Page B を呼び出す" onClick="Call('page_b.html')"><br><br>
        <input type="button" value="Page C を呼び出す" onClick="Call('page_c.html')"><br><br>
    </form>
    
    </body>
    </html>
    
  2. page_a.html, page_b.html, page_c.html を適当な順番に呼び出して下さい。
    右のアンカーをクリックすると Page A が呼び出されます。
    ブラウザのアイコン「←(前のページ), →(次のページ)」でページが移動することを確認して下さい。

  3. 環境によって実行できない場合があり、手順を踏んで実行を確認しながら進めて行きます。
    onload はページが呼び出された時に起動します。
    onunload はページから離れる時に起動します。
    page_b.html を次のように修正して下さい。
    <html>
    <head>
    <meta http-equiv="Content-Script-Type" content="text/javascript" charset="utf-8">
    <title>Page B</title>
    
    <script type="text/javascript">
      window.onload = function()
      {
        window.alert("on load");
      }
      window.onunload = function()
      {
        window.alert("on unload");
      }
      function Call(page)
      {
        location.href = page;
      }
    </script>
    </head>
    
    <body>
    <h2>Page B</h2>
    <form name="Ctrl">
        <input type="button" value="Page A を呼び出す" onClick="Call('page_a.html')"><br><br>
        <input type="button" value="Page B を呼び出す" onClick="Call('page_b.html')"><br><br>
        <input type="button" value="Page C を呼び出す" onClick="Call('page_c.html')"><br><br>
    </form>
    
    </body>
    </html>
    
  4. page_a.html ⇒ page_b.html ⇒ page_c.html の順に呼び出してメッセージを確認して下さい。
    page_a.html ⇒ page_b.html ⇒ ←(前のページ) の順に呼び出してメッセージを確認して下さい。
    onload は起動されても onunload が起動されない場合があります。

  5. onload が起動出来たことを確かめて history Counter を画面に表示します。
    history は呼び出されたページの記録で、history Counter は記録されたページのカウンターです。
    page_c.html を次のように修正して下さい。
    <html>
    <head>
    <meta http-equiv="Content-Script-Type" content="text/javascript" charset="utf-8">
    <title>Page C</title>
    <script type="text/javascript">
      window.onload=getCount;
      function getCount()
      {
        document.getElementById("str").textContent = "history=" + window.history.length;
      }
      function Call(page)
      {
        location.href = page;
      }
    </script>
    </head>
    
    <body>
    <h2>Page C</h2>
    <div id="str">history count</div>
    <form name="Ctrl">
        <input type="button" value="Page A を呼び出す" onClick="Call('page_a.html')"><br><br>
        <input type="button" value="Page B を呼び出す" onClick="Call('page_b.html')"><br><br>
        <input type="button" value="Page C を呼び出す" onClick="Call('page_c.html')"><br><br>
    </form>
    
    </body>
    </html>
    
  6. page_a.html ⇒ page_b.html ⇒ page_c.html を順に呼び出して下さい。
    ページを呼び出す毎にカウントがアップされます。
    page_a.html, page_b.html, page_c.html の順に呼び出すと次のように記録されると思われます。
    記録 説明
    page_a.html Page A を呼び出すときに記録
    page_b.html Page A から Page B を呼び出すときに記録
    page_c.html Page B から Page C を呼び出すときに記録
    ブラウザのアイコン「←(前のページ), →(次のページ)」は、この情報を参照して移動します。
    呼び出しを繰り返して、カウントがアップされることを確認して下さい。
    (2020/4/26 Windows10 & Microsoft Edge 及び Google Chrome で実行を確認しました)。

  7. page_b.html に back と forward を追加します。
    <html>
    <head>
    <meta http-equiv="Content-Script-Type" content="text/javascript" charset="utf-8">
    <title>Page B</title>
    
    <script type="text/javascript">
      function Call(page)
      {
        location.href = page;
      }
      function Back()
      {
        window.history.back();
      }
      function Forward()
      {
        window.history.forward();
      }
    </script>
    </head>
    
    <body>
    <h2>Page B</h2>
    <form name="Ctrl">
        <input type="button" value="Page A を呼び出す" onClick="Call('page_a.html')"><br><br>
        <input type="button" value="Page B を呼び出す" onClick="Call('page_b.html')"><br><br>
        <input type="button" value="Page C を呼び出す" onClick="Call('page_c.html')"><br><br>
        <input type="button" value="Back を呼び出す" onClick="Back()"><br><br>
        <input type="button" value="Forward を呼び出す" onClick="Forward()"><br><br>
    </form>
    
    </body>
    </html>
    
  8. back と forward を呼び出すと、ブラウザの「←(前のページ), →(次のページ)」と同様に動作することを確認して下さい。
    (2020/4/26 Windows10 & Microsoft Edge 及び Google Chrome で実行を確認しました)。

  9. page_c.html に相対的に参照する history.go(相対位置) を追加します。
    window.history.go(-1) が back() と同様で、window.history.go(1) が forward() と同様です。
    <html>
    <head>
    <meta http-equiv="Content-Script-Type" content="text/javascript" charset="utf-8">
    <title>Page C</title>
    
    <script type="text/javascript">
      function Call(page)
      {
        location.href = page;
      }
      function Jump(form)
      {
        var num = form.num.value;
        window.history.go(num);
      }
    </script>
    </head>
    
    <body>
    <h2>Page C</h2>
    <form name="Ctrl">
        <input type="button" value="Page A を呼び出す" onClick="Call('page_a.html')"><br><br>
        <input type="button" value="Page B を呼び出す" onClick="Call('page_b.html')"><br><br>
        <input type="button" value="Page C を呼び出す" onClick="Call('page_c.html')"><br><br>
        <input type="text" name="num" value="-1" size=20><br><br>
        <input type="button" value="JUMP" onClick="Jump(this.form)"><br><br>
    </form>
    
    </body>
    </html>
    
  10. page_a.html ⇒ page_b.html ⇒ page_c.html の順に呼び出して下さい。
    JUMP ボタンをクリックすると -1 が適用され、page_b.html にジャンプします。
    Text Box に -2 をタイプしてクリックすると page_a.html にジャンプします。
    Text Box の値は現在ページから相対的に参照するページの値です。
    (2020/4/26 Windows10 & Microsoft Edge 及び Google Chrome で実行を確認しました)。
    記録 説明
    page_a.html Page A を呼び出すときに記録
    page_b.html Page A から Page B を呼び出すときに記録
    page_c.html Page B から Page C を呼び出すときに記録

  11. page_c.html の getCount() 関数の中で history を書き換えます。
    Page B から Page C を呼び出すと history には Page C が記録されるのですが、これを Page A に書き換えてみます。
    <script type="text/javascript">
      window.onload = getCount;
      function getCount()
      {
        document.getElementById("str").textContent = "history=" + window.history.length;
        history.replaceState(null, "page_a", "page_a.html");
      }
      function Call(page)
      {
        location.href = page;
      }
    </script>
    </head>
    
    <body>
    <h2>Page C</h2>
    <div id="str">history count</div>
    <form name="Ctrl">
        <input type="button" value="Page A を呼び出す" onClick="Call('page_a.html')"><br><br>
        <input type="button" value="Page B を呼び出す" onClick="Call('page_b.html')"><br><br>
        <input type="button" value="Page C を呼び出す" onClick="Call('page_c.html')"><br><br>
    </form>
    
  12. page_a.html ⇒ page_b.html ⇒ page_c.html の順に呼び出して下さい。
    Page C から←(前のページ) で Page B に戻りますが、その後ブラウザの「←(前のページ), →(次のページ)」で移動できるページは Page A と Page B だけになります。
    (2020/4/26 Windows10 & Microsoft Edge で確認したのですが、Google Chrome では replaceState が使えないようです)。
    記録 説明
    page_a.html Page A を呼び出すときに記録
    page_b.html Page A から Page B を呼び出すときに記録
    page_a.html Page C を Page A に書き換えます

  13. page_c.html の onload で history に history.pushState(null, null, null); で空のページを追加します。
    <script type="text/javascript">
      window.onload=getCount;
      function getCount()
      {
        document.getElementById("str").textContent = "history=" + window.history.length;
        history.pushState(null, null, null);
      }
      function Call(page)
      {
        location.href = page;
      }
    </script>
    
  14. page_a.html ⇒ page_b.html ⇒ page_c.html の順に呼び出して下さい。
    ←(前のページ)をクリックすると history に記録されている一つ前のページに移動します。
    空のページを追加したので、←(前のページ)をクリックしても Page C のままです。
    もう一度←(前のページ)をクリックすると Page B に戻り、さらに←(前のページ)で Page A に戻ります。
    (Google Chrome では pushState は利かないようです。)
    記録 説明
    page_a.html Page A を呼び出すときに記録
    page_b.html Page A から Page B を呼び出すときに記録
    page_c.html Page B から Page C を呼び出すときに記録
    null pushState で追加します

  15. 「←(前のページ), →(次のページ)」を検出して、戻りボタンを利かなくする方法を試します。
    ←, → のクリックは addEventListener("popstate", ... ) で知らされます。
    page_c.html で、←, → のクリックを検出して空のページを追加してみましょう。
    <script type="text/javascript">
      window.onload=getCount;
      function getCount()
      {
        document.getElementById("str").textContent = "history=" + window.history.length;
        history.pushState(null, null, null);
      }
      window.addEventListener("popstate", function (e)
      {
        window.alert("← → キー");
        history.pushState(null, null, null);
        return;
      });
      function Call(page)
      {
        location.href = page;
      }
    </script>
    </head>
    
  16. page_a.html ⇒ page_b.html の順に呼び出して下さい。
    Page B から←(前のページ)をクリックすると Page A に戻ります。
    page_a.html ⇒ page_b.html ⇒ page_c.html の順に呼び出して下さい。
    Page C から←(前のページ)を何度クリックしても Page C のままです。
    (2020/4/26 Windows10 & Microsoft Edge で確認しました。)
    (Google Chrome では pushState が利かないので使えません。)

  17. Google Chrome では History API を使って悪いことをやるサイトが多いので、ブロックされているようです。
    仕方が無いので、Page A, Page B, Page C を離れて history_api.html を呼び出すボタンを使うことにします。
    page_c.html を次のように修正して下さい。
    <html>
    <head>
    <meta http-equiv="Content-Script-Type" content="text/javascript" charset="utf-8">
    <title>Page C</title>
    
    <script type="text/javascript">
      function Call(page)
      {
        location.href = page;
      }
    </script>
    </head>
    
    <body>
    <h2>Page C</h2>
    <form name="Ctrl">
        <input type="button" value="Page A を呼び出す" onClick="Call('page_a.html')"><br><br>
        <input type="button" value="Page B を呼び出す" onClick="Call('page_b.html')"><br><br>
        <input type="button" value="Page C を呼び出す" onClick="Call('page_c.html')"><br><br>
        <input type="button" value="history_api.html を呼び出す" onClick="Call('history_api.html')"><br><br>
    </form>
    
    </body>
    </html>
    
  18. page_a.html ⇒ page_b.html ⇒ page_c.html の順に呼び出して下さい。
    Page C から「history_api.html を呼び出す」をクリックして、Page A, Page B, Page C から離れます。
    ←(前のページ)をクリックすると、元の Page C に戻ることが出来ます。

前田稔の超初心者のプログラム入門
超初心者のプログラム入門(JavaScript)