[戻る]ボタンをクリックしたときに、ブラウザ間のonloadイベントはありますか?


185

すべての主要なブラウザー(IEを除く)では、onload戻るボタン操作の結果としてページが読み込まれたときにJavaScript イベントは発生しません。ページが最初に読み込まれたときにのみ発生します。

この問題を解決するサンプルのクロスブラウザコード(Firefox、Opera、Safari、IEなど)を誰かに教えてもらえますか?私はFirefoxのpageshowイベントに精通していますが、残念ながらOperaもSafariもこれを実装していません。


6
これは問題ではありません。ユーザーが[戻る]ボタンを押したときに、Webページをすばやく読み込むことができます。詳細については、以下の私の回答を参照してください。ここで提案されている回避策は、戻る/進むの移動が遅いため、ユーザーにとってWebページをより煩わしくします。
Nickolay、2010

2
@romkyns:コメントはこの質問とは関係ありません。ブラウザがJS / DOM状態を復元しない場合、ブラウザはロードイベントを発生させます。
Nickolay

iOS 5以降の履歴の戻るボタンはここで解決しましたstackoverflow.com/a/12652160/1090395
Mladen Janjetovic

回答:


117

みんな、私はJQueryの効果が1つだけであることを発見しました。ページが戻るボタンが押されたときにページがリロードされます。これは「準備完了」とは関係ありません。

これはどのように作動しますか?さて、JQueryはonunloadイベントリスナーを追加します。

// http://code.jquery.com/jquery-latest.js
jQuery(window).bind("unload", function() { // ...

デフォルトでは何もしません。しかし、どういうわけか、これはSafari、Opera、およびMozillaでリロードをトリガーするようです-イベントハンドラーに何が含まれているかに関係なく。

[ edit(Nickolay):それがそのように機能する理由は次のとおりです:webkit.orgdeveloper.mozilla.org。それらの記事(または下記の別の回答の私の要約)を読んで、本当にこれを行う必要があり、ユーザーのページの読み込みを遅くする必要があるかどうか検討してください。]

信じられない?これを試して:

<body onunload=""><!-- This does the trick -->
<script type="text/javascript">
    alert('first load / reload');
    window.onload = function(){alert('onload')};
</script>
<a href="http://stackoverflow.com">click me, then press the back button</a>
</body>

JQueryを使用すると、同様の結果が表示されます。

あなたはonunloadなしでこれと比較したいかもしれません

<body><!-- Will not reload on back button -->
<script type="text/javascript">
    alert('first load / reload');
    window.onload = function(){alert('onload')};
</script>
<a href="http://stackoverflow.com">click me, then press the back button</a>
</body>

1
これは文書化されていない機能/バグですが、将来のバージョンのブラウザで機能しなくなる可能性がありますが、それでも興味深いものです。
Wadih M.

3
これも機能します(onunload = ""の部分を忘れないでください。それ以外の場合は、ff3では機能しません)。<body onload = "alert( 'onload');" onunload = "">
Wadih M.

3
これは、onunloadハンドラーがある場合、ブラウザーはページがキャッシュ不可であると想定するためです(ページは既にすべてを破棄しています。なぜキャッシュするのですか?)。
Casey Chu

14
最新のブラウザでは回答が機能しないようです-最新のChromeおよびOperaでチェックイン
Andrew

10
iPadサファリでは機能しません...回答のマークを
外し

74

一部の最新のブラウザー(Firefox、Safari、Opera、ただしChromeはサポートしていません)は、ユーザーが[戻る]に移動したときに関与する特別な「バック/フォワード」キャッシュ(Mozillaによって発明された用語であるbfcacheと呼びます)をサポートしています。通常の(HTTP)キャッシュとは異なり、ページの完全な状態(JS、DOMの状態を含む)をキャプチャします。これにより、ユーザーがページを離れたときと同じように、ページをより迅速に再読み込みできます。

loadページはこのbfcacheからロードされたときにイベントが火災に想定されていません。たとえば、「load」ハンドラーでUIを作成し、最初のロードで「load」イベントが1回、ページがbfcacheから2回目に再ロードされたときに、ページは次のようになります。重複するUI要素。

これは、「アンロード」ハンドラーを追加すると、ページがbfcacheに保存されなくなる(そのため、戻るのが遅くなる)理由でもあります。アンロードハンドラーがクリーンアップタスクを実行し、ページが機能しない状態になる可能性があります。

移動先/移動先を知る必要があるページの場合、Firefox 1.5以降バグ28758が修正されたバージョンのSafariは、「pageshow」と「pagehide」と呼ばれる特別なイベントをサポートします。

参照:


それはとてもクールです。現在、私のdom操作がbfcacheに保存されていないようです。あなたがそれを期待するかもしれない状況はありますか?
ベンソン、

1
@ベンソン:Firefoxがページをbfcacheに保存しない可能性のある理由は、リンクしたdev.moページにリストされています。ページをbfcacheに保存することはできないと思いますが、特定のDOM状態は保存されません。
ニコライ

Nickolay、私はあなたがリロードを強制してbfcacheによって行われた良い仕事を取り消すことに抵抗を感じますが、bfcacheのページのdomを更新する別の方法はありますか?たとえば、メッセージのリストがあるページからそのうちの1つに移動し、「戻る」ときに読み取り/未読インジケーターを変更する状況を考えてみます。ページをリロードせずにこれを行うにはどうすればよいですか?
グレッグ

@グレッグ:あなたはページを制御する開発者としての意味ですか?「pageshow」リスナーからのajaxリクエストを開始します。
Nickolay

jQueryを使用して高速なbfcacheサポートを取得する方法に関するアイデアはありますか?
Alex Black

31

ユーザーが前後にクリックしたときにjsが実行されないという問題に遭遇しました。私は最初にブラウザのキャッシュを停止しようとしましたが、これは問題ではないようです。すべてのライブラリーなどがロードされた後に実行するようにJavaScriptが設定されました。これらをreadyStateChangeイベントでチェックしました。

いくつかのテストの後、戻るをクリックしたページの要素のreadyStateが「ロード」されているのではなく「完了」していることがわかりました。追加|| element.readyState == 'complete'条件付きステートメントにと、問題が解決しました。

調査結果を共有したいと思ったところですが、うまくいけば、他の人の役に立つでしょう。

完全性のために編集

私のコードは次のようになりました:

script.onreadystatechange(function(){ 
   if(script.readyState == 'loaded' || script.readyState == 'complete') {
      // call code to execute here.
   } 
});

上記のコードサンプルでは、​​スクリプト変数は、DOMに追加された新しく作成されたスクリプト要素でした。


7
これをどこに追加しましたか?そして、ユーザーが反撃した後、どうやって何かを発射したのですか?コードを見せてください!
Keerigan

「条件文」とはどういう意味ですか?
Phillip Senn、2015

1
@Phillip条件付きステートメントはifステートメントです。
Brian Heese、2015

22

OK、ここにckramerの初期ソリューションと、Operaを含むすべてのブラウザで機能するパレホースの例に基づく最終ソリューションがあります。history.navigationModeを 'compatible'に設定すると、jQueryの準備完了関数は、Operaや他の主要なブラウザーの[戻る]ボタンの操作で起動します。

このページには詳細情報あります

例:

history.navigationMode = 'compatible';
$(document).ready(function(){
  alert('test');
});

私はこれをOpera 9.5、IE7、FF3、Safariでテストしましたが、すべてで動作します。


2
明らかに長い間(約5.5年)ですが、リンクが機能していないことは注目に値します。
ジェフ

2
この解決策は私にはうまくいきません。私はこの問題を最新のFirefox(45.0.1)で持っています
Armin

6

上記の例を機能させることができませんでした。私は単に、戻るボタンを使用してページに戻ったときに、特定の変更されたdiv領域の更新をトリガーしたかっただけです。私が使用したトリックは、div領域が元の領域から変更されるとすぐに、非表示の入力フィールド(「ダーティビット」と呼ばれる)を1に設定することでした。非表示の入力フィールドは、クリックして戻ったときに実際にその値を保持しているため、onloadでこのビットを確認できます。設定されている場合は、ページを更新します(またはdivを更新します)。ただし、元のロードではビットが設定されていないため、ページを2回ロードする時間を無駄にしません。

<input type='hidden' id='dirty'>

<script>
$(document).ready(function() {
  if ($('#dirty').val()) {
    // ... reload the page or specific divs only
  }
  // when something modifies a div that needs to be refreshed, set dirty=1
  $('#dirty').val('1');
});
</script>

そして、[戻る]ボタンをクリックすると、適切にトリガーされます。


3
これはFirefoxでは機能しませんが、非表示フィールドの永続性が非常に役立つIE / Chromeの状況に対処するための賢い方法だと思います。私はあなたのトリックと「pageshow」イベントも使用したので、すべてのメインブラウザーをカバーします。
Magnus Smith

これが機能するpageshowでは、どのブラウザが機能しませんか?
ジャスティン

4

私の記憶が正しければ、unload()イベントを追加すると、ページが(フォワード/バックワードキャッシュに)キャッシュされないことになります。これは、ユーザーがナビゲートすると状態が変化するためです。したがって、履歴オブジェクトをナビゲートしてページに戻るときに、ページの最後の秒の状態を復元するのは安全ではありません。


4

これは、ページの読み込みではなく「onunload」用だと思いました。「戻る」をクリックしたときにイベントを発生させることについて話しているのではないですか?$ document.ready()は、ページの読み込み時に必要なイベント用であり、そのページに到達する方法(つまり、リダイレクト、ブラウザーをURLに直接開くなど)に関係なく、話していない限り、[戻る]をクリックしたときではありません。前のページが再度読み込まれたときに何を起動するかについて。また、$ document.ready()が含まれていても、JavaScriptがまだキャッシュされていることがわかったため、ページがキャッシュされていないかどうかはわかりません。このイベントが含まれるスクリプトを編集するときは、Ctrl + F5キーを押して修正する必要があり、ページで結果をテストする必要があります。

$(window).unload(function(){ alert('do unload stuff here'); }); 

「戻る」を押して現在のページをアンロードするときにonunloadイベントに必要なものであり、ユーザーがブラウザウィンドウを閉じたときにも発生します。$ document.ready()レスポンスで私が数を上回っていたとしても、これは望ましいもののように聞こえました。基本的には、現在のページが閉じているときに発生するイベントと、読み込み中に[戻る]をクリックすると読み込まれるイベントとの違いです。IE 7でテスト済みですが、他のブラウザーは許可されていないため、他のブラウザーでは代用できません。しかし、これは別のオプションかもしれません。


4

jQueryのreadyイベントがIEとFireFoxで機能することをckramerで確認できます。ここにサンプルがあります:

<html>
<head>
    <title>Test Page</title>
    <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
    <script type="text/javascript">
            $(document).ready(function () {
               var d = new Date();
               $('#test').html( "Hi at " + d.toString() );
            });
    </script>
</head>
<body>
    <div id="test"></div>
    <div>
        <a href="http://www.google.com">Go!</a>
    </div>
</body>
</html>

4

jqueryライブラリ全体を使用したくない人のために、実装を個別のコードで抽出しました。大きさはわずか0,4 KBです。

このWikiでは、ドイツ語のチュートリアルとともにコードを見つけることができます。http//www.easy-coding.de/wiki/html-ajax-und-co/onload-event-cross-browser-kompatibler-domcontentloaded.html


1
単独のリンクはそれ自体では意味がなくターゲットリソースが将来も有効であることが保証されていないため、ローンリンクは不適切な回答と見なされます(FAQを参照)。望ましいだろう、ここでの答えの重要な部分を含めて、参照用のリンクを提供します。
j0k 2014年

3

jQueryの readyイベントは、この種の問題のためだけに作成されました。実装を詳しく調べて、内部で何が行われているのかを確認することもできます。


6
しばらくreadyして、[戻る]ボタンを使用しても、Firefoxでトリガーされないようです。Nickolayの回答も参照してください。
アルジャン

2

ビル、私はあえてあなたの質問に答えますが、私の推測では100%確実ではありません。ユーザーが履歴のあるページにアクセスするとき、他のIEブラウザーはページとそのリソースをキャッシュからロードするだけでなく、DOM(読み取りセッション)状態全体を復元すると思います。IEはDOM復元を行わない(または、少なくとも復元は行わなかった)ため、そこでページを適切に再初期化するには、onloadイベントが必要であるように見えます。


2

$(document).ready ...を使用してBillの解決策を試しましたが、最初は機能しませんでした。スクリプトをhtmlセクションの後に配置すると、機能しないことがわかりました。ヘッドセクションの場合、IEでのみ機能します。このスクリプトはFirefoxでは機能しません。


1

OK、私はこれを試しましたが、Firefox 3、Safari 3.1.1、IE7で動作しますが、Opera 9.52 では動作しません
以下に示す例を使用すると(palehorseの例に基づく)、ページが最初にロードされたときにアラートボックスのポップアップが表示されます。ただし、別のURLに移動してから、[戻る]ボタンをクリックしてこのページに戻ると、Operaに警告ボックスのポップアップが表示されません(ただし、他のブラウザでは表示されます)。

とにかく、今のところこれで十分だと思います。みんな、ありがとう!

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<meta http-equiv="expires" content="0">
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready( 
                    function(){
                      alert('test');
                    }
                 );
</script>
</head>
<body>
<h1>Test of the page load event and the Back button using jQuery</h1>
</body>
</html>

1

アンロードイベントがIE 9で正常に機能していません。ロードイベント(onload())で試してみましたが、IE 9およびFF5では正常に機能しています。

例:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
    jQuery(window).bind("load", function() {
        $("[name=customerName]").val('');
    });
</script>
</head>
<body>
    <h1>body.jsp</h1>
    <form action="success.jsp">
        <div id="myDiv">

        Your Full Name: <input name="yourName" id="fullName"
            value="Your Full Name" /><br> <br> <input type="submit"><br>

        </div>

    </form>
</body>
</html>

0

HTMLテンプレートを使用しました。このテンプレートのcustom.jsファイルには、次のような関数が含まれています。

    jQuery(document).ready(function($) {

       $(window).on('load', function() {
          //...
       });

    });

しかし、他のページに移動した後に戻ると、この機能は動作しませんでした。

だから、私はこれを試してみましたがうまくいきました:

    jQuery(document).ready(function($) {
       //...
    });

   //Window Load Start
   window.addEventListener('load', function() {
       jQuery(document).ready(function($) {
          //...
       });
   });

現在、2つの「準備完了」機能がありますが、エラーは発生せず、ページは正常に機能しています。

それにもかかわらず、私はそれがWindows 10-Opera v53およびEdge v42でテストされているが他のブラウザーではテストされていないことを宣言する必要があります。これを覚えておいてください...

注:jqueryのバージョンは3.3.1で、移行のバージョンは3.0.0でした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.