history.replaceState()示例?


127

任何人都可以为history.replaceState提供一个有效的示例吗?这是w3.org所说的:

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

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

更新:

这完美地工作:

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

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


3
通常,我不推送有关JavaScript问题的附加库,但在这种情况下,我将作为例外。该History.js库是一个小垫片,它清理整个现代浏览器的历史API中有很多奇怪的不端行为。它甚至为IE的旧版本提供可选支持。
尖尖的2012年


@Pointy history.js很棒。我已经更新了问题中的代码。不,我的问题是我无法使用浏览器后退按钮返回上一页
Serjas 2012年

3
根据Mozilla的说法,该title参数实际上并未使用。
火箭Hazmat 2012年

3
给定问题的replaceState例子,第一个答案实际上不应该是被接受的答案,而被接受的答案绝不是一个replaceState例子。
Coray,2014年

Answers:


68

确实这是一个错误,尽管有意使用了两年。问题在于一些不清楚的规格和复杂性document.title涉及到前后移动。

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

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

潜在解决方案

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

document.getElementsByTagName('title')[0].innerHTML = 'bar';
window.history.pushState( {} , 'bar', '/bar' );

对于jquery用户..尝试$(“ title”)。html(_title);
suraj jain

3
这可能导致用户需要“双击”后退按钮,具体取决于您如何实现。一个更简单的解决方案可能是继续使用replaceState()并手动设置文档标题document.title = "title"
newshorts

38

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

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()但我不知道您想使用它到底是什么。


2
网址正在更改,但标题未更改..使用最新的chrome @trott测试
Serjas 2012年

6
据我所知,@ Serjas中的title参数replaceState()在所有浏览器中均被忽略。
Trott 2014年

10

history.pushState推动潮流页面状态推送到历史记录堆栈,并更改地址栏中的URL。因此,当您返回时,该状态(传递的对象)将返回给您。

目前,仅此而已。任何其他页面操作,例如显示新页面或更改页面标题,都必须由您完成。

您链接的W3C规范只是草稿,浏览器可能会以不同的方式实现它。 例如,Firefox会忽略title完全参数。

这是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));

29
为什么接受的答案解释为“ pushState”而不是“ replaceState”?
Giwrgos Tsopanoglou

1
@GiwrgosTsopanoglou:我在一年前回答了这个问题,所以我不确定为什么:-P无论如何,replaceState更改当前页面状态。它使您可以更改状态对象和当前页面状态的URL 。
火箭Hazmat 2013年

2
奇怪的是,我一直在寻找关于replaceState的信息,而我最终阅读了关于pushState的信息:P
Giwrgos Tsopanoglou

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;



2

根据MDN历史记录doc
,显然有一个说法是第二个论据是为将来而不是现在使用的。没错,第二个参数是处理网页标题,但是当前所有主流浏览器都将其忽略。

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


第二个参数没有指网页的标题-的MDN文件,让您联系说“通过一个简短的标题为国家到你正在移动。” 。这与W3C 历史记录接口文档所说的“将具有给定标题的给定数据推入会话历史记录”是一致的。该短语中的数据是状态数据,因此标题又是指状态(数据)。
史蒂芬·P

1

我真的很想回应@Sev的回答。

Sev是正确的,内部存在错误 window.history.replaceState

要解决此问题,只需重写构造函数以手动设置标题。

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);
}

2
不要那样做 覆盖默认功能是reaaaally不良作风
勒内·罗斯

3
当需要修复此错误时,您还有什么建议?
Glenn Plas

@GlennPlas针对react repo打开PR :)
zero_cool,

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.