我想用JavaScript看是否有历史记录,后退按钮在浏览器上是否可用。
当前回答
我想出了以下方法。它利用onbeforeunload事件来检测浏览器是否开始离开页面。如果在一定时间内没有,它就会重定向到备用。
var goBack = function goBack(fallback){
var useFallback = true;
window.addEventListener("beforeunload", function(){
useFallback = false;
});
window.history.back();
setTimeout(function(){
if (useFallback){ window.location.href = fallback; }
}, 100);
}
您可以使用goBack("fallback.example.org")调用此函数。
其他回答
还有另一个近乎完美的解决方案,来自于另一个SO答案:
if( (1 < history.length) && document.referrer ) {
history.back();
}
else {
// If you can't go back in history, you could perhaps close the window ?
window.close();
}
有人报告说,当使用target="_blank"时,它不工作,但它似乎在Chrome上为我工作。
简单的回答:你不能。
技术上有一个准确的方法,那就是检查属性:
history.previous
然而,这是行不通的。这样做的问题是,在大多数浏览器中,这被认为是违反安全的,通常只是返回undefined。
history.length
是其他人认为的… 然而,长度并不能完全起作用,因为它不能表明你所处的历史位置。此外,它并不总是从相同的数字开始。例如,一个未设置有登录页的浏览器将从0开始,而另一个使用登录页的浏览器将从1开始。
大多数情况下,添加的链接调用:
history.back();
or
history.go(-1);
如果你不能返回,那么点击链接就没有任何作用。
我用的是window。在我的网站上的常见问题解答。
当用户想退出FAQ时,他们可以点击退出按钮(在后退按钮旁边)
我对这个“退出”策略的逻辑是基于入口ID,然后返回到该状态的状态数。
所以进入:
enterState: { navigationId:number } = {navigationId: 1}
constructor() {
this.enterState = window.history.state
}
假设用户正在浏览FAQ
然后,当用户单击退出按钮时,读取当前状态并计算delta:
exitFaq() {
// when user started in faq, go back to first state, replace it with home and navigate
if (this.enterState.navigationId === 1) {
window.history.go((window.history.state.navigationId - 1) * -1)
this.router.navigateByUrl('/')
// non-angular
// const obj = {Title: 'Home', Url: '/'}
// window.history.replaceState(obj, obj.Title, obj.Url)
} else {
window.history.go(this.enterState.navigationId - window.history.state.navigationId - 1)
}
}
如你所见,我还使用了一个回退当用户开始在faq,在这种情况下,状态。navigationId为1,我们想要路由回去,替换第一个状态,并显示主页(为此我使用Angular路由器,但你也可以使用历史记录。当你处理自己的路由时,也可以使用replaceState)
供参考:
history.go history.state history.replaceState Angular.router.navigateByUrl
你不能直接检查后退按钮是否可用。你可以看看历史。长度为>0,但如果在当前页之前还有页,这也是成立的。只有当history.length===0时,才能确定后退按钮不可用。
如果这还不够好,你所能做的就是调用history.back(),如果你的页面之后仍然被加载,返回按钮是不可用的!当然,这意味着如果后退按钮可用,则您刚刚导航离开了页面。你不允许取消onunload中的导航,所以你所能做的就是从onbeforeunload中返回一些东西,这将导致一个恼人的大提示符出现。这不值得。
事实上,用历史做任何事情通常都是一个非常糟糕的主意。历史导航是chrome浏览器,不是网页。添加“返回”链接通常会引起更多用户的困惑,而不是它的价值。
解决方案
'use strict';
function previousPage() {
if (window.location.pathname.split('/').filter(({ length }) => length > 0).length > 0) {
window.history.back();
}
}
解释
window.location.pathname会给你当前的URI。例如,https://domain/question/1234/i-have-a-problem会给出/question/1234/i-have-a-problem。请参阅有关窗口的文档。获取更多信息的位置。
接下来,调用split()将为我们提供该URI的所有片段。所以如果我们使用我们之前的URI,我们将会有像["","question", "1234", "i-have-a-problem"]这样的东西。有关更多信息,请参阅有关String.prototype.split()的文档。
这里调用filter()来过滤掉由反斜杠生成的空字符串。它基本上只返回长度大于1的URI片段(非空字符串)。所以我们会有像["question", "1234", "i-have-a-question"]这样的东西。这可以写成这样:
'use strict';
window.location.pathname.split('/').filter(function(fragment) {
return fragment.length > 0;
});
有关更多信息,请参阅关于Array.prototype.filter()和析构赋值的文档。
现在,如果用户在https://domain/上尝试返回,我们不会触发if语句,也不会触发window.history.back()方法,这样用户就会留在我们的网站中。这个URL将等价于长度为0的[],0 > 0为假值。因此,默默的失败。当然,如果您愿意,您可以记录一些内容或其他操作。
'use strict';
function previousPage() {
if (window.location.pathname.split('/').filter(({ length }) => length > 0).length > 0) {
window.history.back();
} else {
alert('You cannot go back any further...');
}
}
限制
当然,如果浏览器不支持History API,这个解决方案将不起作用。在使用此解决方案之前,请查看文档以了解更多信息。