138

任何人都可以举一个history.replaceState的工作示例吗?这就是w3.org所说的:

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

更新会话历史记录中的当前条目以具有给定的数据、标题和 URL(如果提供且不为空)。


更新

这完美地工作:

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

URL 正在更改,但标题未更改。这是一个错误还是我错过了什么?在最新的 Chrome 上测试。

4

9 回答 9

70

确实这是一个错误,尽管现在是故意的 2 年。问题在于一些不清楚的规格以及document.title涉及到后退/前进时的复杂性。

请参阅WebkitMozilla上的错误参考。此外,Opera 在介绍 History API时表示它没有使用 title 参数,并且可能仍然没有。

目前,pushState 和 replaceState 的第二个参数——历史条目的标题——没有在 Opera 的实现中使用,但可能有一天。

潜在的解决方案

我看到的唯一方法是更改​​标题元素并改用 pushState:

document.getElementsByTagName('title')[0].innerHTML = 'bar';
window.history.pushState( {} , 'bar', '/bar' );
于 2012-10-15T09:29:07.763 回答
41

这是一个最小的,人为的例子。

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()但我不知道你想用它做什么。

于 2012-10-11T04:49:35.417 回答
9

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));
于 2012-10-16T15:07:48.550 回答
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

于 2012-10-16T09:45:29.140 回答
2

第二个参数标题并不意味着页面的标题 - 它更多的是该页面状态的定义/信息

但是我们仍然可以使用onpopstate事件更改标题,并且不是从第二个参数传递标题名称,而是作为第一个参数的属性作为对象传递

参考: http ://spoiledmilk.com/blog/html5-chang-the-browser-url-without-refreshing-page/

于 2014-03-20T07:10:18.073 回答
2

根据MDN History doc
有明确的说法,第二个参数是用于未来而不是现在。没错,第二个参数是处理网页标题,但目前所有主要浏览器都忽略了它。

Firefox 当前忽略此参数,尽管它可能在未来使用它。在此处传递空字符串应该可以安全地防止将来对该方法进行更改。或者,您可以为您要迁移到的州传递一个简短的标题。

于 2015-03-12T06:22:58.693 回答
1

I really wanted to respond to @Sev's answer.

Sev is right, there is a bug inside the window.history.replaceState

To fix this simply rewrite the constructor to set the title manually.

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);
}
于 2015-09-15T18:23:54.740 回答
0

将此视为 URL:http://localhost:4200/inspections/report-details/60c88e4e76b14c00193f5bef

let reportId = '60c88e4e76b14c00193f5bef', scope = "dynamic"

window.history.replaceState(null, null, `inspections/report-details/${reportId}?damagePart=` + scope );

这将产生输出 http://localhost:4200/inspections/report-details/60c88e4e76b14c00193f5bef?damagePart=dynamic/

于 2021-06-17T09:23:19.760 回答
0

假设https://www.mozilla.org/foo.html执行以下 JavaScript:

const stateObj = { foo: 'bar' };

history.pushState(stateObj, '', 'bar.html');

这将导致 URL 栏显示https://www.mozilla.org/bar2.html,但不会导致浏览器加载 bar2.html 甚至检查 bar2.html 是否存在。

于 2020-05-22T12:53:53.897 回答