101

この質問は、ユーザーがブラウザの[戻る]ボタンを押したときの追跡に似ていますが、同じではありません...解決策があり、参照とフィードバックのためにここに投稿しています。誰かがもっと良い選択肢を持っているなら、私はすべての耳です!

状況は、私が「インプレース編集」、laflickrを備えたページを持っているということです。つまり、「ここをクリックして説明を追加」DIVがあり、クリックすると[保存]ボタンと[キャンセル]ボタンのあるTEXTAREAに変わります。[保存]をクリックすると、データがサーバーに送信されてデータベースが更新され、TEXTAREAの代わりに新しい説明がDIVに配置されます。ページが更新されると、「クリックして編集」オプションを使用して、データベースから新しい説明が表示されます。最近はかなり標準的なWeb2.0のものです。

問題は次の場合です。

  1. ページは説明なしで読み込まれます
  2. 説明はユーザーによって追加されます
  3. リンクをクリックしてページから移動します
  4. ユーザーが戻るボタンをクリックする

次に、(ブラウザのキャッシュから)表示されるのは、動的に変更されたDIVに新しい説明が含まれていないページのバージョンです。

これはかなり大きな問題です。ユーザーは更新が失われたと想定し、変更を確認するためにページを更新する必要があることを必ずしも理解していないためです。

したがって、問題は次のとおりです。ページの読み込み後に変更されたページにフラグを立て、ユーザーが「ページに戻った」ことを検出して、その状況で強制的に更新するにはどうすればよいでしょうか。

4

11 に答える 11

80

非表示のフォームを使用します。フォーム データは、リロードするか、[戻る] ボタンを押してページに戻ると、ブラウザーに (通常は) 保持されます。次はあなたのページに入れます(おそらく一番下の近く):

<form name="ignore_me">
    <input type="hidden" id="page_is_dirty" name="page_is_dirty" value="0" />
</form>

JavaScript では、次のものが必要になります。

var dirty_bit = document.getElementById('page_is_dirty');
if (dirty_bit.value == '1') window.location.reload();
function mark_page_dirty() {
    dirty_bit.value = '1';
}

フォームをスニッフィングする js は、html が完全に解析された後に実行する必要がありますが、ユーザーの待ち時間が深刻な懸念事項である場合は、フォームと js の両方をページの上部 (js 秒) にインラインで配置できます。

于 2011-04-12T22:58:59.807 に答える
64

これは、この古い問題に対する非常に簡単な最新の解決策です。

if (window.performance && window.performance.navigation.type === window.performance.navigation.TYPE_BACK_FORWARD) {
    alert('Got here using the browser "Back" or "Forward" button.');
}

window.performance は現在、すべての主要なブラウザーでサポートされています。

于 2017-08-24T09:31:39.287 に答える
13

この記事ではそれについて説明します。以下のコードを参照してください: http://www.webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/

<html>
    <head>
        <script>

            function pageShown(evt){
                if (evt.persisted) {
                    alert("pageshow event handler called.  The page was just restored from the Page Cache (eg. From the Back button.");
                } else {
                    alert("pageshow event handler called for the initial load.  This is the same as the load event.");
                }
            }

            function pageHidden(evt){
                if (evt.persisted) {
                    alert("pagehide event handler called.  The page was suspended and placed into the Page Cache.");
                } else {
                    alert("pagehide event handler called for page destruction.  This is the same as the unload event.");
                }
            }

            window.addEventListener("pageshow", pageShown, false);
            window.addEventListener("pagehide", pageHidden, false);

        </script>
    </head>
    <body>
        <a href="http://www.webkit.org/">Click for WebKit</a>
    </body>
</html>
于 2011-06-15T22:05:18.983 に答える
7

onbeforeunloadイベントを使用して解決できます。

window.onbeforeunload = function () { }

onbeforeunloadの空のイベント マネージャー関数があるということは、ページがアクセスされるたびに再構築されることを意味しますJavascript が再実行され、サーバー側スクリプトが再実行され、ユーザーが [戻る] ボタンまたは [進む] ボタンを押しただけでページにアクセスした場合でも、ユーザーが初めてクリックしたかのようにページが構築されます。 .

例の完全なコードは次のとおりです。

<html>
<head>
<title>onbeforeunload.html</title>
<script>
window.onbeforeunload = function () { }

function myfun()
{
   alert("The page has been refreshed.");
}
</script>

<body onload="myfun()">

Hello World!<br>

</body>
</html>

試してみて、このページから離れてから、ブラウザの「戻る」または「進む」ボタンを使用して戻ってください。

IE、FF、Chrome で問題なく動作します。

もちろん、 myfun関数内でやりたいことは何でもできます。

詳細: http://www.hunlock.com/blogs/Mastering_The_Back_Button_With_Javascript

于 2015-06-04T04:05:30.663 に答える
2

上記のように、私は解決策を見つけ、参照とフィードバックのためにここに投稿しています。

ソリューションの最初の段階は、ページに以下を追加することです。

<!-- at the top of the content page -->
<IFRAME id="page_is_fresh" src="fresh.html" style="display:none;"></IFRAME>
<SCRIPT style="text/javascript">
  function reload_stale_page() { location.reload(); }
</SCRIPT>

の内容はfresh.html重要ではないため、以下で十分です。

<!-- fresh.html -->
<HTML><BODY></BODY></HTML>

クライアント側のコードがページを更新するとき、次のように変更にフラグを立てる必要があります。

function trigger_reload_if_user_clicks_back_button()
{
  // "dis-arm" the reload stale page function so it doesn't fire  
  // until the page is reloaded from the browser's cache
  window.reload_stale_page = function(){};

  // change the IFRAME to point to a page that will reload the 
  // page when it loads
  document.getElementById("page_is_fresh").src = "stale.html";
}

stale.htmlすべての作業を行います。ロードされると、reload_stale_page必要に応じてページを更新する関数を呼び出します。初めてロードされたとき(つまり、変更が行われた後、reload_stale_page関数は何もしません)。

<!-- stale.html -->
<HTML><BODY>
<SCRIPT type="text/javascript">window.parent.reload_stale_page();</SCRIPT>
</BODY></HTML>

この段階での私の(最小限の)テストから、これは希望どおりに機能しているようです。私は何かを見落としましたか?

于 2009-05-06T11:07:04.913 に答える
1

このページを使用して、特に @Nick White とこのページの回答に関する @sajith のコメントを組み込みます: http://www.mrc-productivity.com/techblog/?p=1235

<form name="ignore_me" style="display:none">
    <input type="text" id="reloadValue" name="reloadValue" value="" />
</form>

$(function ()
{
    var date = new Date();
    var time = date.getTime();

    if ($("#reloadValue").val().length === 0)
    {
        $("#reloadValue").val(time);
    }
    else
    {
        $("#reloadValue").val("");
        window.location.reload();
    }
});
于 2016-02-26T04:20:01.577 に答える
0

今日も同様の問題に遭遇し、localStorage で解決しました (ここでは少し jQuery を使用):

$(function() {

    if ($('#page1').length) {
        // this code must only run on page 1

        var checkSteps = function () {
            if (localStorage.getItem('steps') == 'step2') {
                // if we are here, we know that:
                // 1. the user is on page 1
                // 2. he has been on page 2
                // 3. this function is running, which means the user has submitted the form
                // 4. but steps == step2, which is impossible if the user has *just* submitted the form
                // therefore we know that he has come back, probably using the back button of his browser
                alert('oh hey, welcome back!');
            } else {
                setTimeout(checkSteps, 100);
            }
        };

        $('#form').on('submit', function (e) {
            e.preventDefault();
            localStorage.setItem('steps', 'step1'); // if "step1", then we know the user has submitted the form
            checkOrderSteps();
            // ... then do what you need to submit the form and load page 2
        });
    }

    if ($('#page2').length) {
        // this code must only run on page 2
        localStorage.setItem('steps', 'step2');
    }

});

Si基本的に:

ページ 1 で、ユーザーがフォームを送信すると、localStorage に値「steps」を設定して、ユーザーが実行したステップを示します。同時に、この値が変更されたかどうかを確認するタイムアウト付きの関数を起動します (例: 10 回/秒)。

2 ページ目で、すぐに値を変更します。

したがって、ユーザーが [戻る] ボタンを使用し、ブラウザがページ 1 を元の状態に戻すと、checkSteps 関数は引き続き実行され、localStorage の値が変更されたことを検出できます (そして、適切なアクションを実行できます)。 )。このチェックが目的を達成したら、それを実行し続ける必要はないので、単に setTimeout を使用しません。

于 2016-06-08T15:29:17.773 に答える
0

他の誰かからのコメントでこれを見つけました(Mladenに感謝します)-Chrome 88で非常にうまく機能するようです.

if(String(window.performance.getEntriesByType("navigation")[0].type) === "back_forward"){
// Actions here, such as refresh page, etc.
}
于 2021-02-05T19:38:09.943 に答える