オン-window.location.hash-変更?


558

私はナビゲーションにAjaxとハッシュを使用しています。

window.location.hashこのように変更されたかどうかを確認する方法はありますか?

http://example.com/blah #123http://example.com/blah #456

ドキュメントの読み込み時にチェックすると機能します。

しかし、#hashベースのナビゲーションがある場合、ブラウザーの戻るボタンを押しても機能しません(そのため、blah#456からblah#123にジャンプします)。

アドレスボックス内に表示されますが、JavaScriptではキャッチできません。


6
このjqueryプラグインをチェックアウト:github.com/cowboy/jquery-hashchange
Xavi

9
History.jsはHTML5の状態管理機能をサポートしているため(これ以上ハッシュを使用する必要はありません!)、ハッシュ変更を使用してHTML4ブラウザーに正常に分解します。jQuery、MooTools、Prototypeをそのまま使用できます。
balupton 2011年

@balupton、実際には、URL変更をフィードバックとして使用しない限り、「新しいページ」が履歴に挿入されたことをユーザーにフィードバックするために、ハッシュを使用する必要があります。
Pacerier 2014年


うーん...私はあなたがモアjQuery
RaisingAgent

回答:


617

これを実際に行う唯一の方法(および「reallysimplehistory」がこれを行う方法)は、現在のハッシュをチェックし続ける間隔を設定し、それを以前と比較して、これを行い、サブスクライバーに変更をサブスクライブさせますハッシュが変更された場合に発生するイベントです。完全ではありませんが、ブラウザはこのイベントをネイティブでサポートしていません。


この回答を最新の状態に保つための更新:

jQueryを使用している場合(今日のほとんどは基本的なものです)、優れたソリューションは、jQueryが提供する抽象化を使用して、イベントシステムを使用し、ウィンドウオブジェクトのハッシュ変更イベントをリッスンすることです。

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

ここでの良い点は、ハッシュ変更のサポートについても心配する必要がないコードを記述できることですが、あまり知られていないjQuery機能jQuery特別なイベントの形で、何らかの魔法をかける必要があります

この機能を使用すると、基本的には、何らかのイベント(イベントへのバインドなど)で誰かがイベントを使用しようとしたときに、何らかのイベントのセットアップコードを実行できます。

このセットアップコードでは、ネイティブブラウザーのサポートを確認できます。ブラウザーがこれをネイティブに実装していない場合は、単一のタイマーを設定して変更をポーリングし、jQueryイベントをトリガーできます。

これにより、コードがこのサポートの問題を理解する必要から完全に解放されます。この種の特別なイベントの実装は簡単です(単純な98%の動作バージョンを取得するため)が、なぜ他の誰かがすでにそうしているのにそうするのです


7
IE8にはあります。もっと来て
セルゲイIlinsky

28
最新のFirefoxビルド(3.6アルファ版)でも、ネイティブのハッシュ変更イベントがサポート れています。 IE7互換モードで実行しているときに存在します。悲しいことにイベントは発生しません。イベントを確認する必要があり、ブラウザがIE7でないように見えます。 IEのfireEventメソッドを使用)。
meandmycode 2009

8
執筆時点では、WebKitもhashchangeイベントを発生させますが、Safari(安定版)はまだ発生させません。
jholster 2010

51
さらに別の更新を追加するために、hashchangeイベントが広くサポートされるようになりました:caniuse.com/#search=hash
Paystey

19
自発的なjQueryの回答が苦痛だと思うのは私だけですか?
Luc

290

HTML5 hashchangeイベントを指定します。このイベントは現在、すべての最新ブラウザーでサポートされています。次のブラウザバージョンでサポートが追加されました。

  • Internet Explorer 8
  • Firefox 3.6
  • Chrome 5
  • Safari 5
  • Opera 10.6

20
更新:FF 5、Safari 5、およびChrome 12は、2011
。– james.garriss

2
これがhashchangeのCanIUseページです。これがquirksmodeのhashchangeです。IEのサポートは、大文字と小文字の区別に関してバグがあります。
東武

3
@everybody、コメントセクションの回答に追加し続ける必要はありません。それが「編集」ボタンの目的です。:)
マイケル・マーティン・スマッカー

15
使用法:window.onhashchange = function() { doYourStuff(); }
Chris

4
hashchangeイベントの MDNドキュメント。
Dabowheel、2015年

52

Internet Explorer 7およびInternet Explorer 9の場合、ifステートメントはtrueになりますが(ウィンドウの「onhashchange」の場合)、これは起動しwindow.onhashchangeません。したがって、ハッシュを保存し、100ミリ秒ごとに変更されたかどうかを確認することをお勧めします。Internet Explorerのすべてのバージョン。

    if (("onhashchange" in window) && !($.browser.msie)) {
         window.onhashchange = function () {
              alert(window.location.hash);
         }
         // Or $(window).bind( 'hashchange',function(e) {
         //       alert(window.location.hash);
         //   });
    }
    else {
        var prevHash = window.location.hash;
        window.setInterval(function () {
           if (window.location.hash != prevHash) {
              prevHash = window.location.hash;
              alert(window.location.hash);
           }
        }, 100);
    }

編集-jQuery 1.9以降、$.browser.msieサポートされていません。ソース:http : //api.jquery.com/jquery.browser/


14

IEブラウザーでは、Historyとwindow.location.hashを処理するための多くのトリックがあります。

  • 元の質問で述べたように、ページa.html#bからa.html#cに移動してから[戻る]ボタンを押すと、ブラウザはページが変更されたことを認識しません。例を挙げましょう。window.location.hrefは、a.html#bでもa.html#cでも、 'a.html#c'になります。

  • 実際、a.html#bとa.html#cは、要素「<a name="#b">」と「<a name="#c">」がページ内に以前に存在する場合にのみ履歴に保存されます。

  • ただし、ページ内にiframeを配置した場合は、そのiframe内でa.html#bからa.html#cに移動し、[戻る]ボタンをクリックすると、iframe.contentWindow.document.location.hrefが期待どおりに変更されます。

  • コードで'document.domain = something ' を使用すると、iframe.contentWindow.document.open()にアクセスできなくなります(多くの履歴マネージャーがこれを行います)。

これは本当の反応ではないことは知っていますが、IE-Historyのノートは誰かにとって役立つかもしれません。



11

Ben Almanには、これを処理するための優れたjQueryプラグインがあります。http://benalman.com/projects/jquery-hashchange-plugin/

jQueryを使用していない場合は、dissectへの興味深い参照になるかもしれません。


Ben Almanプラグインはもうメンテナンスされていないようです。ただし、いくつかの分岐があります。
Mnebuerquo 2015

9

「window.location」オブジェクトの「hash」プロパティにオブザーバー(「watch」メソッド)を簡単に実装できます。

Firefoxには、オブジェクトの変更を監視するための独自の実装がありますが、他の実装(JavaScriptでオブジェクトプロパティの変更監視するなど)を使用する場合、他のブラウザの場合はこれでうまくいきます。

コードは次のようになります。

window.location.watch(
    'hash',
    function(id,oldVal,newVal){
        console.log("the window's hash value has changed from "+oldval+" to "+newVal);
    }
);

次に、それをテストできます。

var myHashLink = "home";
window.location = window.location + "#" + myHashLink;

そしてもちろん、それはあなたのオブザーバー機能をトリガーします。


より良い使用法:window.locationの代わりにwindow.location.href。
Codebeat

3
彼はwindow.locationではなくwindow.location.hashを見ています。
未定義

1
@BrianMortenson:ドキュメント(developer.mozilla.org/en-US/docs/JavaScript/Reference/…)によると、watch変更するプロパティを所有し、それを監視するオブジェクトに適用する必要があります。
gion_13 2012

@ gion_13はい、それはまさに私が指摘しようとしていたことです。「彼」とは私があなたを意味し、アーウィヌスのコメントに向けられたものです。もっとはっきりしていたはずです。明確なコメントをありがとう。
未定義

7

これを反応アプリケーションで使用して、ユーザーがどのビューを使用しているかに応じて、URLに異なるパラメーターを表示させました。

私はハッシュパラメータを使用して見ました

window.addEventListener('hashchange', doSomethingWithChangeFunction());

その後

doSomethingWithChangeFunction () { 
    // Get new hash value
    let urlParam = window.location.hash;
    // Do something with new hash value
};

御馳走を働いた、前方と後方のブラウザーボタンで、またブラウザーの履歴で動作します。


1
あなたのaddEventListener電話では、あなたは()から削除する必要がありますdoSomethingWithChangeFunction
ジェイソンS

()を削除する理由を教えてください。私はそれがどちらでも動作することを知っています、そしてより少ないコードがほとんどの方が良いオプションですが、これをバックアップする実質的な理由がない限りこれはうるさいようです?
Sprose

6
?で動作しないはず()です。のaddEventListener関数は、関数に渡す必要があります。doSomethingWithChangeFunction関数です。doSomethingWithChangeFunction()その関数の戻り値です。この場合は関数ではありません。
Jason S

6

まともな実装はhttp://code.google.com/p/reallysimplehistory/にあります。唯一(かつ)の問題とバグは次のとおりです。InternetExplorerでロケーションハッシュを手動で変更すると、履歴スタック全体がリセットされます(これはブラウザの問題であり、解決できません)。

Internet Explorer 8は「hashchange」イベントをサポートしていることに注意してください。これはHTML5の一部になりつつあるため、他のブラウザーが追いつくことが期待できます。


1

もう1つの優れた実装はjQuery Historyですです。jQuery履歴は、ブラウザーでサポートされている場合はネイティブのonhashchangeイベントを使用し、そうでない場合はブラウザーでiframeまたは間隔を適切に使用して、期待されるすべての機能が正常にエミュレートされるようにします。また、特定の状態にバインドするための優れたインターフェースも提供します。

同様に注目に値する別のプロジェクトは、jQuery Ajaxyです。これは、jQuery履歴がajaxをミックスに追加するための拡張です。ハッシュでajaxを使い始めると、かなり複雑になります。


1
var page_url = 'http://www.yoursite.com/'; // full path leading up to hash;
var current_url_w_hash = page_url + window.location.hash; // now you might have something like: http://www.yoursite.com/#123

function TrackHash() {
    if (document.location != page_url + current_url_w_hash) {
        window.location = document.location;
    }
    return false;
}
var RunTabs = setInterval(TrackHash, 200);

それだけです...これで、[戻る]または[進む]ボタンを押すたびに、新しいハッシュ値に従ってページがリロードされます。


eval文字列を使用しない
Vitim.us 2013

1

私はクライアント側のルーティングにpath.jsを使用しています。私はそれが非常に簡潔で軽量であることがわかり(NPMにも公開されています)、ハッシュベースのナビゲーションを利用しています。

path.js NPM

path.js GitHub


0

私はjQueryプラグインHUtilを使用し、その上にYUI Historyのようなインターフェースを記述しました。

一度チェックしてください。あなたが助けを必要とするなら、私は助けることができます。

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