この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、CX事業本部 IoT事業部の若槻です。
今回は、JavaScriptのHistory.pushState()
メソッドの動作を確認してみました。
History.pushState()とは
history.pushState()
は、Webブラウザの履歴に状態を追加できるメソッドです。
パラメーターは次の3つです。
state
:履歴に追加したいオブジェクトを指定。title
:通常は使用されないため、空文字を指定。url
(オプション):履歴に追加したいURL文字列を指定。
次の実装はstateを指定しつつ、hello-world.html
パスを履歴に追加している例です。
const state = { 'page_id': 1, 'user_id': 5 }
const title = ''
const url = 'hello-world.html'
history.pushState(state, title, url)
また次の実装はfoo=bar
のクエリパラメータを履歴に追加している例です。
const url = new URL(window.location);
url.searchParams.set('foo', 'bar');
window.history.pushState({}, '', url);
動作確認
ここまでの説明だけだとピンと来ないと思うので、ボタンクリックでhistory.pushState()
を行うデモアプリで動作を確認してみます。
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<script type="text/javascript">
const buttonClick1 = () => {
const state = { page_id: 1, user_id: 5 };
const title = '';
const url = 'hello-world.html';
window.history.pushState(state, title, url);
};
const buttonClick2 = () => {
const state = { page_id: 2, user_id: 8 };
const url = new URL(window.location);
url.searchParams.set('foo', 'bar');
window.history.pushState(state, '', url);
};
</script>
<body>
<h1>Hello Vanilla!</h1>
<input
type="button"
value="hello world"
onclick="buttonClick1()"
/>
<input
type="button"
value="foo bar"
onclick="buttonClick2()"
/>
</body>
</html>
下記デモアプリのボタンをクリックすると、ナビゲーションバーのURLが変更されることが確認できます。ナビゲーションバーの戻る/進むボタンも使えるかと思います。
またhistory.state
を使用すると、履歴に格納されたstateを取得することができます。
デモアプリでボタンクリックにより履歴を追加した上で、history.state
をブラウザで実行すると、最後にhistory.pushState
した際のstateを取得できます。
Reactにおけるhistory.pushState()
さて、URLを変更するだけのhistory.pushState()
メソッドがどんなところで使われるかと言うと、ReactなどのSingle Page ApplicationでのRoutingライブラリなどを通して使うことになります。
Single Page ApplicationではWebアプリへの最初のアクセス時にJavaScriptコードのいくつかの大きな塊をダウンロードします。以降のアプリ内でのページ遷移ではスクリプトによるページコンテンツの書き換えとRoutingライブラリによるURLの変更が行われることにより、仮想的なページ遷移が行われるため、ユーザーからすると高速なページ遷移が行われているように感じ、ユーザーエクスペリエンスの向上に繋がります。このRoutingライブラリにおいてhistory.pushState()
が使われています。
おわりに
JavaScriptのHistory.pushState()
メソッドの動作を確認してみました。
React Routerを使う機会があったのですが、少しとっつきにくさを感じたため、まずはバニラなHistory APIから触ってみた、という経緯がありました。これでReact Routerの理解も進みそうです。
参考
- CodeSandboxの埋め込みオプションまとめ(後編) | DevelopersIO
- JavaScriptのhistory.pushState()とは? – Rainbow Engine
- ルーティング機能を自作して学ぶ History API - 30歳からのプログラミング
以上