history.replaceState()の例?


127

だれでもhistory.replaceStateの実用的な例を示すことができますか?これはw3.orgが言うことです:

history . replaceState(data, title [, url ] )

セッション履歴の現在のエントリを更新して、指定されたデータ、タイトル、および指定されていてnullでない場合はURLを指定します。

更新:

これは完全に機能します:

history.replaceState( {} , 'foo', '/foo' );

URLは変更されていますが、タイトルは変更されていません。それはバグですか、それとも何か不足していますか?最新のChromeでテスト済み。


3
通常、JavaScriptの質問にはアドオンライブラリをプッシュしませんが、この場合は例外を作成します。History.jsのライブラリーは、近代的なブラウザ間で履歴APIに奇妙な不正行為の多くをクリーンアップし、小さなシムです。古いバージョンのIEのオプションのサポートも提供します。
先のとがった


@Pointy history.jsはうまく動作します。質問のコードを更新しました。ブラウザの[戻る]ボタンで前のページに戻れないのは問題ありません
Serjas

3
Mozillaによると、このtitleパラメーターは実際には使用されていません。
ロケットハズマット2012年

3
質問がreplaceState例を求めていることを考えると、最初の回答は実際には受け入れられた回答であってはならず、受け入れられた回答は決してreplaceState例ではありません。
CorayThan 2014年

回答:


68

確かにこれはバグですが、2年間は意図的です。問題は、いくつかの不明確な仕様と、document.titleバック/フォワードが関係する場合の複雑さにあります。

WebkitおよびMozillaのバグリファレンスを参照してください。また、History APIの導入に関するOperaは、titleパラメータを使用しておらず、おそらくまだ使用していないと述べています。

現在、pushStateとreplaceStateの2番目の引数(履歴エントリのタイトル)は、Operaの実装では使用されていませんが、1日になる場合があります。

可能な解決策

私が見る唯一の方法は、title要素を変更して、代わりにpushStateを使用することです。

document.getElementsByTagName('title')[0].innerHTML = 'bar';
window.history.pushState( {} , 'bar', '/bar' );

jqueryユーザーの場合は、$( "title")。html(_title);を試してください。
suraj jain 16

3
これにより、実装方法によっては、ユーザーが戻るボタンを「ダブルクリック」する必要が生じる可能性があります。より簡単な解決策は、使い続けてreplaceState()ドキュメントのタイトルを手動で設定することかもしれませんdocument.title = "title"
newshorts

38

これは、最小限の、不自然な例です。

console.log( window.location.href );  // whatever your current location href is
window.history.replaceState( {} , 'foo', '/foo' );
console.log( window.location.href );  // oh, hey, it replaced the path with /foo

他にもありますが、それをreplaceState()どうしたいのか正確にはわかりません。


2
URLは変更されますが、タイトルは変更されません..最新のクロムでテストされました@trott
Serjas

6
@SerjasのtitleパラメーターreplaceState()は、私の知る限りでは、すべてのブラウザーで無視されています。
Trott

10

history.pushState現在のページの状態を履歴スタックにプッシュし、アドレスバーのURLを変更します。したがって、戻ると、その状態(渡したオブジェクト)が返されます。

現在、それだけです。新しいページの表示やページタイトルの変更など、その他のページアクションは、ユーザーが行う必要があります。

リンクするW3C仕様は単なるドラフトであり、ブラウザによって実装が異なる場合があります。 たとえば、Firefoxtitleパラメータを完全に無視します。

これはpushState私が私のウェブサイトで使用する簡単な例です。

(function($){
    // Use AJAX to load the page, and change the title
    function loadPage(sel, p){
        $(sel).load(p + ' #content', function(){
            document.title = $('#pageData').data('title');
        });
    }

    // When a link is clicked, use AJAX to load that page
    // but use pushState to change the URL bar
    $(document).on('click', 'a', function(e){
        e.preventDefault();
        history.pushState({page: this.href}, '', this.href);
        loadPage('#frontPage', this.href);
    });

    // This event is triggered when you visit a page in the history
    // like when yu push the "back" button
    $(window).on('popstate', function(e){
        loadPage('#frontPage', location.pathname);
        console.log(e.originalEvent.state);
    });
}(jQuery));

29
なぜ受け入れられた回答が「replaceState」ではなく「pushState」を説明するのですか?
Giwrgos Tsopanoglou 2013

1
@GiwrgosTsopanoglou:私はこれを1年前に回答したので、なぜだかわかりません:-Pとにかく、replaceState現在のページの状態を変更します。現在のページ状態の状態オブジェクトとURLを変更できます。
Rocket Hazmat 2013

2
それは私がpushStateについて読んでしまったreplaceStateとIについての情報を探していたということだけで奇妙だった:P
Giwrgos Tsopanoglou

6

例を見てください

window.history.replaceState({
    foo: 'bar'
}, 'Nice URL Title', '/nice_url');

window.onpopstate = function (e) {
    if (typeof e.state == "object" && e.state.foo == "bar") {
        alert("Blah blah blah");
    }
};

window.history.go(-1);

そして検索location.hash;


2

2番目の引数Titleは、ページのタイトルを意味するものではありません-これは、そのページの状態に関する定義/情報の詳細です

しかし、onpopstateイベントを使用してタイトルを変更し、2番目の引数からではなく、オブジェクトとして渡される最初のパラメーターの属性としてタイトル名を渡すことができます。

リファレンス:http : //spoiledmilk.com/blog/html5-changing-the-browser-url-without-refreshing-page/


2

MDN History docによれば
、第2の議論は、現在ではなく、将来に向けたものであると明確に述べられています。2番目の引数はWebページのタイトルに関するものですが、現在のところ、すべての主要なブラウザでは無視されています。

Firefoxは現在このパラメータを無視していますが、将来使用する可能性があります。ここに空の文字列を渡すと、メソッドが将来変更されても安全です。または、移動先の州の短いタイトルを渡すこともできます。


2番目の引数、Webページのタイトルを参照していませ —リンクしたMDNドキュメントは、「移動先の州の短いタイトルを渡す」と言っています。。これは、W3C 履歴インターフェイスのドキュメントに「指定されたタイトルで、指定されたデータをセッション履歴にプッシュする」と一致しています。その句のデータは州のデータなので、タイトルは州(データ)を指します。
Stephen P

1

@Sevの答えに本当に応えたかった。

Sevは正しいです、内部にバグがあります window.history.replaceState

これを修正するには、コンストラクターを書き直して、タイトルを手動で設定します。

var replaceState_tmp = window.history.replaceState.constructor;
window.history.replaceState.constructor = function(obj, title, url){
    var title_ = document.getElementsByTagName('title')[0];
    if(title_ != undefined){
        title_.innerHTML = title;
    }else{
        var title__ = document.createElement('title');
        title__.innerHTML = title;
        var head_ = document.getElementsByTagName('head')[0];
        if(head_ != undefined){
            head_.appendChild(title__);
        }else{
            var head__ = document.createElement('head');
            document.documentElement.appendChild(head__);
            head__.appendChild(title__);
        }
    }
    replaceState_tmp(obj,title, url);
}

2
しないでください。デフォルトの機能を上書きすると、reaaaally悪いスタイルです
ルネ・ロス

3
このバグを修正する必要がある場合、他に何を提案しますか?
Glenn Plas 2017年

@GlennPlasが反応リポジトリに対してPRをオープンします:)
zero_cool

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