web-dev-qa-db-ja.com

戻るボタンをクリックしたときにクロスブラウザのonloadイベントがありますか?

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

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

177
Bill

皆さん、JQueryには1つの効果しかありません。戻るボタンが押されると、ページがリロードされます。これは「ready」とは関係ありません。

これはどのように作動しますか?さて、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>
112

最近のブラウザ(Firefox、Safari、Opera、ただしChromeではありません)の一部は、ユーザーが戻る操作に関係する特別な「戻る/進む」キャッシュ(Mozillaが発明した用語であるbfcacheと呼びます)をサポートします。通常の(HTTP)キャッシュとは異なり、ページの完全な状態(JS、DOMの状態を含む)をキャプチャします。これにより、ユーザーがページを離れたときよりも速く、正確にページを再ロードできます。

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

また、「アンロード」ハンドラーを追加すると、ページがbfcacheに保存されなくなります(そのため、ナビゲートするのが遅くなります)-アンロードハンドラーがクリーンアップタスクを実行し、ページが実行不能な状態になる可能性があります。

Firefox 1.5以降および bug 28758 を修正したSafariのバージョンでは、いつナビゲート/戻るかを知る必要があるページについて、「pageshow」および「pagehide」と呼ばれる特別なイベントをサポートしています。

参照:

72
Nickolay

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

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

私が私の発見を共有すると思っただけで、うまくいけば彼らは他の誰かを助けるでしょう。

完全を期して編集

私のコードは次のように見えました。

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

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

31
Brian Heese

OK、これはckramerの最初のソリューションと、Operaを含むすべてのブラウザで動作するpalehorseの例に基づいた最終ソリューションです。 history.navigationModeを 'compatible'に設定すると、jQueryの準備完了関数は、Operaおよび他の主要なブラウザーの[戻る]ボタン操作で起動します。

このページには 詳細 があります。

例:

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

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

21
Bill

上記の例を動作させることができませんでした。戻るボタンでページに戻ったときに、特定の変更された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>

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

6
thorie

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

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

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

4
Tom

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

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

4
Torben Brodt

正しく覚えていれば、unload()イベントを追加すると、ページが(フォワード/バックワードキャッシュで)キャッシュできないことを意味します。これは、ユーザーが別の場所に移動すると状態が変わる/変わる可能性があるためです。そのため、履歴オブジェクトをナビゲートしてページに戻るときに、ページの最後の2番目の状態を復元することは安全ではありません。

4
arcijsg

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
palehorse

jQuery'sready この種の問題のためにイベントが作成されました。実装を掘り下げて、裏側で何が起こっているのかを確認することができます。

3
ckramer

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

2
Sergey Ilinsky

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

2
Johann

アンロードイベントは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>
1
mallesham

OK、これを試してみましたが、Firefox 3、Safari 3.1.1、およびIE7では動作しますが、_-Opera 9.52ではnotです。
以下に示す例を使用すると(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
Bill

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でした

0
bafsar