Javascript 在不重新加载页面的情况下修改查询字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10970078/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 03:50:05  来源:igfitidea点击:

Modifying a query string without reloading the page

javascriptjqueryquery-stringdhtml

提问by Sonic Soul

I am creating a photo gallery, and would like to be able to change the query string and title when the photos are browsed.

我正在创建一个照片库,并希望能够在浏览照片时更改查询字符串和标题。

The behavior I am looking for is often seen with some implementations of continuous/infinite page, where while you scroll down the query string keeps incrementing the page number (http://x.com?page=4) etc.. This should be simple in theory, but I would like something that is safe across major browsers.

我正在寻找的行为经常出现在一些连续/无限页面的实现中,当你向下滚动查询字符串时,它会不断增加页码(http://x.com?page=4)等等。这应该是理论上很简单,但我想要在主要浏览器中安全的东西。

I found this great post, and was trying to follow the example with window.history.pushstate, but that doesn't seem to be working for me. And I'm not sure if it is ideal because I don't really care about modifying the browser history.

我找到了这篇很棒的帖子,并试图按照示例进行操作window.history.pushstate,但这似乎对我不起作用。而且我不确定它是否理想,因为我并不真正关心修改浏览器历史记录。

I just want to be able to offer the ability to bookmark the currently viewed photo, without reloading the page every time the photo is changed.

我只是希望能够为当前查看的照片添加书签,而无需在每次更改照片时重新加载页面。

Here is an example of infinite page that modifies query string: http://tumbledry.org/

以下是修改查询字符串的无限页面示例:http: //tumbledry.org/

UPDATEfound this method:

更新发现这个方法:

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

it appears to work for me, but i am on a new chrome.. it would probably cause some issues with older browsers?

它似乎对我有用,但我使用的是新的 chrome.. 它可能会导致旧浏览器出现一些问题?

回答by Fabio Nolasco

If you are looking for Hash modification, your solution works ok. However, if you want to change the query, you can use the pushState, as you said. Here it is an example that might help you to implement it properly. I tested and it worked fine:

如果您正在寻找哈希修改,则您的解决方案可以正常工作。但是,如果您想更改查询,则可以使用 pushState,如您所说。这是一个可以帮助您正确实施它的示例。我测试过,效果很好:

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

It does not reload the page, but it only allows you to change the URL query. You would not be able to change the protocol or the host values. And of course that it requires modern browsers that can process HTML5 History API.

它不会重新加载页面,但它只允许您更改 URL 查询。您将无法更改协议或主机值。当然,它需要可以处理 HTML5 History API 的现代浏览器。

For more information:

想要查询更多的信息:

http://diveintohtml5.info/history.html

http://diveintohtml5.info/history.html

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

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

回答by jmona789

Building off of Fabio's answer, I created two functions that will probably be useful for anyone stumbling upon this question. With these two functions, you can call insertParam()with a key and value as an argument. It will either add the URL parameter or, if a query param already exists with the same key, it will change that parameter to the new value:

基于 Fabio 的回答,我创建了两个函数,这些函数可能对遇到这个问题的任何人都有用。使用这两个函数,您可以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 to add/update query params
function insertParam(key, value) {
    if (history.pushState) {
        // var newurl = window.location.protocol + "//" + window.location.host + search.pathname + '?myNewUrlQuery=1';
        var currentUrlWithOutHash = window.location.origin + window.location.pathname + window.location.search;
        var hash = window.location.hash
        //remove any param for the same key
        var currentUrlWithOutHash = removeURLParameter(currentUrlWithOutHash, key);

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

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

回答by Ian Newson

I've used the following JavaScript library with great success:

我已经成功地使用了以下 JavaScript 库:

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

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

It supports the HTML5 history API as well as a fallback method (using #) for older browsers.

它支持 HTML5 历史 API 以及旧浏览器的回退方法(使用 #)。

This library is essentially a polyfill around `history.pushState'.

这个库本质上是一个围绕“history.pushState”的 polyfill。

回答by Aram Hovhannisyan

I want to improve Fabio's answer and create a function which adds custom key to the URL string without reloading the page.

我想改进 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);
    }
}

回答by chucktator

Then the history API is exactly what you are looking for. If you wish to support legacy browsers as well, then look for a library that falls back on manipulating the URL's hash tag if the browser doesn't provide the history API.

那么历史 API 正是您正在寻找的。如果您也希望支持旧版浏览器,那么在浏览器不提供历史 API 的情况下,寻找一个依赖于操作 URL 哈希标签的库。