javascript 在不引起页面刷新的情况下设置 URL 参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22258793/
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-10-27 22:47:20  来源:igfitidea点击:

Set URL parameters without causing page refresh

javascriptjqueryurlquery-stringhtml5-history

提问by Don P

How can you set URL parameters using History.pushState()to avoid browser refreshes? If there is a not a simple JS solution, is there already a popular library or built in function for jQuery?

如何设置 URL 参数History.pushState()以避免浏览器刷新?如果没有简单的 JS 解决方案,是否已经有流行的 jQuery 库或内置函数?

Here is a relevant SO question, where the accepted answer does not actually work according to comments & my test (it removes the query string instead of updating a value): history.pushState() change query values

这是一个相关的 SO 问题,根据评论和我的测试,其中接受的答案实际上不起作用(它删除了查询字符串而不是更新值):history.pushState() 更改查询值

Just to be clear, I am referring to the URL parameters in a query string: http://google.com/page?name=donso we could change donto timwithout causing a reload.

为了清楚起见,我指的是查询字符串中的 URL 参数: http://google.com/page?name=don因此我们可以更改dontim而不会导致重新加载。

Here is one possible solutionI found. However I'm nervous about using a JS library that only has 2 followers :P

这是我找到的一种可能的解决方案。但是,我对使用只有 2 个关注者的 JS 库感到紧张:P

回答by Don P

You can just use queryString.push('my_param_key', 'some_new_value')from the small library below.

您可以queryString.push('my_param_key', 'some_new_value')从下面的小库中使用。

It will update your URL param using history.push, so the browser will not refresh.

它将使用 history.push 更新您的 URL 参数,因此浏览器不会刷新。

It will only affect the param you wish to change, it will leave the path and other params unaffected.

它只会影响您希望更改的参数,而不会影响路径和其他参数。

/*!
    query-string
    Parse and stringify URL query strings
    https://github.com/sindresorhus/query-string
    by Sindre Sorhus
    MIT License
*/
(function () {
    'use strict';
    var queryString = {};

    queryString.parse = function (str) {
        if (typeof str !== 'string') {
            return {};
        }

        str = str.trim().replace(/^\?/, '');

        if (!str) {
            return {};
        }

        return str.trim().split('&').reduce(function (ret, param) {
            var parts = param.replace(/\+/g, ' ').split('=');
            var key = parts[0];
            var val = parts[1];

            key = decodeURIComponent(key);
            // missing `=` should be `null`:
            // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
            val = val === undefined ? null : decodeURIComponent(val);

            if (!ret.hasOwnProperty(key)) {
                ret[key] = val;
            } else if (Array.isArray(ret[key])) {
                ret[key].push(val);
            } else {
                ret[key] = [ret[key], val];
            }

            return ret;
        }, {});
    };

    queryString.stringify = function (obj) {
        return obj ? Object.keys(obj).map(function (key) {
            var val = obj[key];

            if (Array.isArray(val)) {
                return val.map(function (val2) {
                    return encodeURIComponent(key) + '=' + encodeURIComponent(val2);
                }).join('&');
            }

            return encodeURIComponent(key) + '=' + encodeURIComponent(val);
        }).join('&') : '';
    };

    queryString.push = function (key, new_value) {
    var params = queryString.parse(location.search);
    params[key] = new_value;
    var new_params_string = queryString.stringify(params)
    history.pushState({}, "", window.location.pathname + '?' + new_params_string);
  }

    if (typeof module !== 'undefined' && module.exports) {
        module.exports = queryString;
    } else {
        window.queryString = queryString;
    }
})();

回答by Oscar Paz

Answering to the question in your comment, you'd be able to read those properties from history.state, a property that holds the value of the stat for the current URL. Whenever you go back and forward you'll receive a popstateevent and you will be able tor read the state you pushed, which is far easier than dealing with urls.

回答您评论中的问题,您将能够从 读取这些属性history.state,该属性保存当前 URL 的 stat 值。每当您前后移动时,您都会收到一个popstate事件,并且您将能够读取推送的状态,这比处理 url 容易得多。

Of course, when you go back or forward to a new entry in the history list pushed with pushState()or replaceState()the page does not reload.

当然,当您返回或前进到推入的历史列表中的新条目时,pushState()或者replaceState()页面不会重新加载。

You can read more about the History object in the MDN.

您可以在MDN 中阅读有关 History 对象的更多信息。

回答by Philip Rittenhouse Jr.

Here is a simple function I wrote it isn't as neat as the above answer but it does the trick...

这是我写的一个简单的函数,它不像上面的答案那么简洁,但它确实有效......

            function changeUrlParam (param, value) {
                var currentURL = window.location.href;
                var urlObject = currentURL.split('?');
                var newQueryString = '?';

                value = encodeURIComponent(value);

                if(urlObject.length > 1){
                    var queries = urlObject[1].split('&');

                    var updatedExistingParam = false;
                    for (i = 0; i < queries.length; i++){
                        var queryItem = queries[i].split('=');

                        if(queryItem.length > 1){
                             if(queryItem[0] == param){
                                newQueryString += queryItem[0] + '=' + value + '&';
                                updatedExistingParam = true;
                             }else{
                                newQueryString += queryItem[0] + '=' + queryItem[1] + '&';
                             }
                        }
                    }
                    if(!updatedExistingParam){
                        newQueryString += param + '=' + value + '&';
                    }
                }else{
                    newQueryString += param + '=' + value + '&';
                }
                window.history.replaceState('', '', urlObject[0] + newQueryString.slice(0, -1));
            }