この記事では主にHTML5の履歴で提供されているpushStateとreplaceStateAPIを記録します。最後に、これらの API を使用して小規模なルーティングを自分で実装します。
window.history によって提供される API については、Mozilla ドキュメントを参照してください。
history によって提供される PushState および replaceState API は、ブラウザ履歴スタックを操作するためのメソッドを提供します。
pushState:
history.pushState(data, null, '#/page=1'); pushState接收3个参数,第一个参数为一个obj,表示浏览器 第二个参数是document.title的值,一般设定为`null` 第三个参数string,用以改变 当前url
pushState メソッドは、URL の変更中に新しい履歴レコードをブラウザ履歴スタックにプッシュします。
URL を受け取るパラメータは文字列型であり、現在のアドレス バーの URL を変更するために使用されます。注意すべき点は、このパラメータをクロスドメイン、つまりプロトコルやドメインと同じにすることはできないということです。名前とポートは同じである必要があります。クロスドメインの場合は、次のプロンプトが表示されます。
Uncaught DOMException: Failed to execute 'pushState' on 'History': A history state object with URL 'http://www.baidu.com/' cannot be created in a document with origin 'http://commanderXL.com' and URL
Example:
打开www.baidu.com history.pushState(null, null, '?page=1') //地址栏变成 www.baidu.com/?page=1 history.pushState(null, null, '#page=2'); //地址栏变成 www.baidu.com/#page=2
where replaceState:
history.replaceState(null, null, '#page=2');
replaceState は、pushState と同じパラメータを受け取ります。ただし、最終的な効果は次のとおりです。アドレス バーの URL は受信したパラメーターに従って変更されますが、ブラウザーは閲覧していません。 ブラウザーの履歴は履歴スタックに追加されますが、現在のブラウザーの履歴は置き換えられます。
URL は、pushState および replaceState を通じて変更できますが、ブラウザーのリロードをアクティブにトリガーすることはありません。
window オブジェクトは、popstate メソッドも提供します:
window.addEventListener('popstate', function() { });
このメソッドは、ブラウザーのさまざまな履歴レコード間の切り替えを監視し、対応するイベントをトリガーするために使用されます。
ユーザーがブラウザの「進む」ボタンと「戻る」ボタンをクリックすることをシミュレートするために、ブラウザーによって提供される履歴オブジェクトには go メソッドと back メソッドもあります。例えば、あるWebアプリケーションでは、gt;をクリックするとページがジャンプします。このとき、history.back(); メソッドの呼び出し後にページが戻り、同時にページが更新されます。このとき、window.onpopstate はこのイベントを監視できません。ただし、ブラウザを更新せずに、pushState または replaceState を通じて URL が変更された場合は、popstate イベントがトリガーされるように、history.back() またはhistory.go() を使用します。
history.pushState({page: 1}, null, '?page=1'); history.pushState({page: 2}, null, '?page=2'); history.back(); //浏览器后退 window.addEventListener('popstate', function(e) { //在popstate事件触发后,事件对象event保存了当前浏览器历史记录的状态. //e.state保存了pushState添加的state的引用 console.log(e.state); //输出 {page: 1} });
追記: location.search を通じて検索コンテンツを取得するには、pushState を通じて URL に ?page=1 を追加します。ただし、location.search を通じて URL を変更すると、ブラウザのリロードがアクティブにトリガーされます。この機能は、以下のハッシュに関するコンテンツと比較できます。
API について一般的に理解できたところで、これらのメソッドはどこに適用できるでしょうか?より一般的なシナリオは、単一ページ アプリケーションでこれらの API を使用してフロントエンド ルーティング設計を完了することです。pushState と replaceState を使用してブラウザーを更新せずに URL を変更し、popstate を使用してブラウザーの履歴を監視して一連の非同期を完了します。行動。
addRoute('/login', function() { //do something }) //路由处理 const routeHandle = (path) => { Router.forEach((item, index) => { if(item.path === path) { item.handle.apply(null, [path]); return true; } }) return false; } //拦截默认的a标签行为 document.addEventListener('click', function(e) { let dataset = e.target.dataset; if(dataset) { if(routeHandle(dataset.href)) { //阻止默认行为 e.preventDefault(); } } })
一般的な考え方は、 を通じてルーティング情報を追加し、その後、 タグのデフォルトの動作をインターセプトし、それを登録されたルーティング情報と照合することです。一致が成功すると、対応するハンドル メソッドが呼び出されます
ただし、pushState メソッドと replaceState メソッドは、IE ブラウザの以前のバージョンとの互換性があまりありません。したがって、ダウングレードして、ルーティング設計にハッシュを使用できます。
ハッシュ?突いてください。
location.hash を介して URL の最初の #(フラグメント) と次のコンテンツを取得できます。同時に、ブラウザーのリロードをアクティブにトリガーせずに、location.hash を通じてそのコンテンツを書き換えることができます。 一部の関数は、pushState および replaceState と同じですか? そのため、下位バージョンのブラウザと互換性を持たせるために、変更を監視して配線設計を行うことができます。
では、どうやって監視するのでしょうか? より大雑把な方法の 1 つはポーリングです。
var oldHash = location.hash; setTimeInterval(function() { if(oldHash !== location.hash) { //do something oldHash = location.hash; } }, 100);
ただし、H5 は API: hashchange も提供します。上記のポーリング方法を直接置き換えて # の変更を監視できます。
window.addEventListener('hashchange', function() { routeHandle(locaiton.hash); });
この小さなルーティング設計は、私の github にあります。
ちょっとした要約:
上記では主に、ハッシュの歴史と関連知識によって提供されるいくつかの API を紹介します。通常時には、Gmail はルーティング設計にハッシュを使用します。ページ ジャンプとの比較:
ページをロードする必要があるのは 1 回だけです。後でページを切り替えると、ajax を介してデータをリクエストできます。ページ エクスペリエンスがよりスムーズになります
ローカル キャッシュを使用してページ エクスペリエンスを最適化できます。異なるページ間の切り替えプロセスがよりスムーズになり、
をオンデマンドで読み込むことができます。
などの実用的な利点があります。