0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[JavaScript][メモ]popstateイベントをサンプルコードで挙動確認

Posted at

はじめに

(注)「~が解決した」みたいな記事じゃなくて、popstateイベントについてのメモです。

業務中、とある画面でブラウザボタンを押すとbfcache(ブラウザバック時に使うキャッシュ)が悪さをして、想定外の挙動をしてしまう、という状態だった

状況

A画面

①↓ ↑② ↓③

B画面

①ボタンを押して画面遷移(POST送信による遷移)

②ブラウザバックで画面遷移

③再度ボタンを押して画面遷移→①でキャッシュに保存された値でリクエストしてしまいエラー
(具体的には、楽観ロックエラー)

対応策としてのpopstateイベント

この時に②でブラウザバックで遷移後、この「ブラウザバックしたこと」を検知して、ブラウザバックしたのであれば、強制的にリロードしてしまおう、と考えました。

サンプルコードで試してみる

いくつか記事を拝見しましたが、自分の理解力が乏しく自分のやりたいように動いてくれるかわからなかったので、サンプルコードを自作して挙動を確認

A画面

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>A</title>
    <script>
    history.replaceState(null, null, null);
    window.addEventListener('popstate', function(e) {
        alert('popstate!!');
    });
    </script>
</head>
<body>
    <h1>indexAです</h1>
    <a href="./indexB.html">Bへ遷移</a>
</body>
</html>

いくつか書いてある参考記事(本記事文末)通りですが、

history.replaceState(null, null, null);

これで、この画面の履歴(history)を置き換えます。

大事なのは第3引数で、ここはhistoryに保存するurlを指定します。
nullにすると現在のurlを保存するようになります。

そして、次に同じ画面に遷移した際にhistoryを上書きします。

 window.addEventListener('popstate', function(e) {
        alert('popstate!!');
    });

ここではブラウザバックされた際の処理を書いています。

今回は先ほどのreplaceStatusで必ずhistoryに履歴が保存されるので、必ずブラウザバックした際にこの処理を実行することになります。

popstatusはブラウザの履歴が変更された際に発火するイベント

B画面

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>B</title>
</head>
<body>
    <h1>indexBです</h1>
    <p>ブラウザバックしてください</p>
</body>
</html>

ただの遷移用のページです。

想定では、ここに遷移したらブラウザバックして、遷移先でalertが動く挙動です。

挙動結果

完全に想定していた挙動ではありませんでした。実際の挙動は以下の通り。

A画面・・・③

①↓ ↑②

B画面

①ボタンを押して画面遷移(POST送信による遷移)

②ブラウザバックで画面遷移・・・※ここで検知してほしかったが機能せず

③再度ブラウザバックしようとするとpopstateイベントが発火し、alertが実行

③でpopstateイベントが発火するので、今回のやりたいことは実現できなさそう。。。

結論

今回はこのpopstateを使った解決はできないと判断し、他の方法で解決しました。

とはいえ、完全にブラウザバックを禁止して単一的な遷移フローのサイトを作る場合はいいかもですね。
(あんまりユーザーライクじゃない気も、、、)

参考記事

参考にさせていただき、ありがとうございました。

https://zenn.dev/k_kudo/articles/9b3633f4beb0b2

https://yutaihara.com/archives/512

https://qiita.com/dkdkd335/items/5749cd740d876a9b88d5

https://rainbow-engine.com/javascript-popstate-trigger/

最後に

たかが1つのJSのAPIの理解に時間かけちゃいましたが、想定通りに動いてくれないとわかったので、まあよしとします。

こうやってゆっくりでも知見を広げて、JSと仲良くなれればと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?