web-dev-qa-db-ja.com

ページをリロードせずにクエリ文字列を変更する

フォトギャラリーを作成していますが、写真の閲覧時にクエリ文字列とタイトルを変更できるようにしたいと考えています。

私が探している動作は、連続/無限ページの一部の実装でよく見られます。クエリ文字列を下にスクロールしている間、ページ番号が増加し続けます( http://x.com?page=4 )など。これは理論的には単純なはずですが、主要なブラウザ間で安全なものが欲しいです。

この素晴らしい投稿 を見つけ、window.history.pushstateを使用してサンプルを追おうとしていましたが、それは私には役に立たないようです。また、ブラウザの履歴を変更することはあまり気にしないので、それが理想的かどうかはわかりません。

写真が変更されるたびにページをリロードせずに、現在表示されている写真をブックマークする機能を提供したいだけです。

クエリ文字列を変更する無限ページの例を次に示します。 http://tumbledry.org/

UPDATEこのメソッドが見つかりました:

window.location.href = window.location.href + '#abc';

それは私のために働くように見えますが、私は新しいクロムを使用しています..それはおそらく古いブラウザでいくつかの問題を引き起こすでしょうか?

84
Sonic Soul

ハッシュの変更を探している場合、ソリューションは正常に機能します。ただし、クエリを変更する場合は、前述のようにpushStateを使用できます。これは、適切に実装するのに役立つ例です。私はテストし、うまくいきました:

if (history.pushState) {
    var newurl = window.location.protocol + "//" + window.location.Host + window.location.pathname + '?myNewUrlQuery=1';
    window.history.pushState({path:newurl},'',newurl);
}

ページはリロードされませんが、URLクエリの変更のみが許可されます。プロトコルまたはホスト値を変更することはできません。そしてもちろん、HTML5 History APIを処理できる最新のブラウザーが必要です。

詳細については:

http://diveintohtml5.info/history.html

https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history

145
Fabio Nolasco

次のJavaScriptライブラリを使用して大成功しました。

https://github.com/balupton/jquery-history

HTML5履歴APIと、古いブラウザー用のフォールバックメソッド(#を使用)をサポートします。

このライブラリは、本質的に「history.pushState」を囲むポリフィルです。

6
Ian Newson

Fabioの答えを基に、この質問につまずいた人にとっておそらく役立つ2つの関数を作成しました。これらの2つの関数を使用すると、キーと値を引数としてinsertParam()を呼び出すことができます。 URLパラメーターを追加するか、同じキーを持つクエリパラメーターが既に存在する場合、そのパラメーターを新しい値に変更します。

//function to remove query params from a URL
function removeURLParameter(url, parameter) {
    //better to use l.search if you have a location/link object
    var urlparts= url.split('?');   
    if (urlparts.length>=2) {

        var prefix= encodeURIComponent(parameter)+'=';
        var pars= urlparts[1].split(/[&;]/g);

        //reverse iteration as may be destructive
        for (var i= pars.length; i-- > 0;) {    
            //idiom for string.startsWith
            if (pars[i].lastIndexOf(prefix, 0) !== -1) {  
                pars.splice(i, 1);
            }
        }

        url= urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : "");
        return url;
    } else {
        return url;
    }
}

function insertParam(key, value) {
    if (history.pushState) {
        // var newurl = window.location.protocol + "//" + window.location.Host + search.pathname + '?myNewUrlQuery=1';
        var currentUrl = window.location.href;
        //remove any param for the same key
        var currentUrl = removeURLParameter(currentUrl, key);

        //figure out if we need to add the param with a ? or a &
        var queryStart;
        if(currentUrl.indexOf('?') !== -1){
            queryStart = '&';
        } else {
            queryStart = '?';
        }

        var newurl = currentUrl + queryStart + key + '=' + value
        window.history.pushState({path:newurl},'',newurl);
    }
}
4
jmona789

履歴APIはまさにあなたが探しているものです。レガシーブラウザもサポートする場合は、ブラウザが履歴APIを提供していない場合にURLのハッシュタグを操作することに頼るライブラリを探します。

0
chucktator

Fabioの答えを改善し、ページをリロードせずにURL文字列にカスタムキーを追加する関数を作成します。

function insertUrlParam(key, value) {
    if (history.pushState) {
        let searchParams = new URLSearchParams(window.location.search);
        searchParams.set(key, value);
        let newurl = window.location.protocol + "//" + window.location.Host + window.location.pathname + '?' + searchParams.toString();
        window.history.pushState({path: newurl}, '', newurl);
    }
}
0