关于javascript:更改URL而不刷新页面

Change URL without refresh the page

本问题已经有最佳答案,请猛点这里访问。

我想替换一个没有页面刷新的URL。

我需要改变:

1
https://example.com/en/step1

1
https://example.com/en/step2

怎么做?


更新

基于对浏览器历史的操作,将空字符串作为pushState方法(又称标题)的第二个参数传递应该是安全的,以防将来对该方法进行更改,因此最好使用pushState这样:

1
history.pushState(null, '', '/en/step2');

你可以在上面的文章中了解更多。

原始答案

使用history.pushState如下:

1
history.pushState(null, null, '/en/step2');
  • 更多信息(MDN文章):操作浏览器历史记录
  • 我能用吗?
  • 也许你应该看看@Internet Explorer是否支持PushState和ReplaceState?

更新2以回答idan dagan的评论:

Why not using history.replaceState()?

从多点传送

history.replaceState() operates exactly like history.pushState() except that replaceState() modifies the current history entry instead of creating a new one

这意味着,如果您使用replaceState,则URL将被更改,但用户不能使用浏览器的后退按钮返回到prev。状态不再存在(因为replaceState不会在历史中添加新条目),因此不建议使用它,并且提供糟糕的用户体验。

更新3以添加window.onpopstate

因此,当您注意到这个答案时,下面是关于操作浏览器历史记录的附加信息,在使用pushState之后,您可以像这样使用window.onpopstate来检测后退/前进按钮导航:

1
2
3
window.onpopstate = function(e) {
    // ...
};

由于pushState的第一个论点是一个对象,如果您通过了object而不是null,那么您可以访问onpopstate中的该对象,这非常方便,下面是如何:

1
2
3
4
5
window.onpopstate = function(e) {
    if(e.state) {
        console.log(e.state);
    }
};

更新4以添加读取当前状态:

当您的页面加载时,它可能有一个非空状态对象,您可以在不等待popstate事件的情况下使用history.state属性读取当前历史记录条目的状态,如下所示:

1
console.log(history.state);

奖励:使用以下选项检查history.pushState支持:

1
2
3
if (history.pushState) {
  // \o/
}


使用函数时…

1
2
3
4
5
6
7
<p onclick="update_url('/en/step2');">Link
</p>


function update_url(url) {
    history.pushState(null, null, url);
}