修改查询字符串而不重新加载页面

Son*_*oul 90 javascript jquery dhtml query-string

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

我正在寻找的行为常见于连续/无限页面的一些实现,其中当您向下滚动查询字符串时,不断增加页码(http://x.com?page=4)等.这应该是理论上很简单,但我希望在主流浏览器中安全.

我找到了这篇伟大的帖子,并试图跟随这个例子window.history.pushstate,但这似乎并不适合我.而且我不确定它是否理想,因为我并不真正关心修改浏览器历史记录.

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

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

UPDATE发现了这个方法:

window.location.href = window.location.href + '#abc';
Run Code Online (Sandbox Code Playgroud)

它似乎适合我,但我是一个新的铬..它可能会导致旧浏览器的一些问题?

Fab*_*sco 158

如果您正在寻找哈希修改,您的解决方案可以正常工作.但是,如果要更改查询,可以使用pushState,如您所述.这是一个可以帮助您正确实现它的示例.我测试过,它工作正常:

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

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

欲获得更多信息:

http://diveintohtml5.info/history.html

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

  • 请注意,如果您不希望新状态出现在浏览器历史记录中,则可以使用具有相同参数的`history.replaceState()`. (20认同)
  • 我相信你可以将`window.location.protocol +'//'+ window.location.host`简化为:`window.location.origin`. (5认同)
  • 使用history.replaceState(),否则您需要在浏览器中单击两次BACK按钮 (5认同)
  • 此外,对于一个额外的信息位,相对路径也与`history.pushState()`一起工作.也不需要实际的`state`参数.这两个意味着你可以做一些简单的事情,比如`history.pushState(null,'','/ foo?bar = true')`如果你的新网址在同一个主机/端口上. (4认同)
  • 在现代浏览器中你可以这样做:```if(window.history.pushState){const newURL = new URL(window.location.href); newURL.search ='?myNewUrlQuery = 1'; window.history.pushState({path:newURL.href},'',newURL.href); }``` (4认同)
  • 在 Firefox 中,您需要使用完全限定的 URL。仅路径会产生安全错误。 (2认同)

小智 63

老问题,现代答案来帮助未来的开发人员;使用URL接口:

const url = new URL(window.location);
url.searchParams.set('key', value);
window.history.pushState(null, '', url.toString());
Run Code Online (Sandbox Code Playgroud)

这可确保您确实只更改所需的查询参数。

  • 是的 。你是对的。我说错了。 (2认同)

Ara*_*yan 27

我想改进 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);
    }
}
Run Code Online (Sandbox Code Playgroud)


laz*_*vab 13

如果我们只是想更新查询参数而不触及 URL 的其他部分,则无需再次构建 URL。这就是我使用的:

const addQueryParam = (key, value) => {
  const url = new URL(window.location.href);
  url.searchParams.set(key, value);
  window.history.pushState({}, '', url.toString());
};

const getQueryParam = (key) => {
  const url = new URL(window.location.href);
  return url.searchParams.get(key) || '';
};
Run Code Online (Sandbox Code Playgroud)


Ian*_*son 6

我使用了以下JavaScript库并取得了巨大成功:

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

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

这个库本质上是一个围绕`history.pushState'的polyfill.


jmo*_*789 5

在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 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 任何版本的 IE 都不支持 `new URLSearchParams()` (2认同)
  • ...并且 IE 不受任何人支持。 (2认同)