【发布时间】:2011-04-05 00:53:34
【问题描述】:
我想使用 JavaScript 来查看是否有历史记录,我的意思是浏览器上的后退按钮是否可用。
【问题讨论】:
-
如果您的目的是检查
goback是否正常工作,我认为您可以在回退调用之后设置一个计时器......因此如果goback不起作用,您可以重定向到后备链接。
标签: javascript
我想使用 JavaScript 来查看是否有历史记录,我的意思是浏览器上的后退按钮是否可用。
【问题讨论】:
goback 是否正常工作,我认为您可以在回退调用之后设置一个计时器......因此如果goback 不起作用,您可以重定向到后备链接。
标签: javascript
简短回答:你不能。
从技术上讲,有一种准确的方法,那就是检查属性:
history.previous
但是,它不起作用。问题在于,在大多数浏览器中,这被视为安全违规,通常只返回 undefined。
history.length
是其他人建议的属性...
但是,长度不能完全起作用,因为它没有指示您在历史中的位置是。此外,它并不总是以相同的数字开头。例如,未设置登录页面的浏览器从 0 开始,而使用登录页面的另一个浏览器将从 1 开始。
大多数情况下,添加的链接会调用:
history.back();
或
history.go(-1);
如果您无法返回,那么单击该链接将无济于事。
【讨论】:
还有另一种检查方法 - 检查引荐来源网址。第一页通常会有一个空的referer...
if (document.referrer == "") {
window.close()
} else {
history.back()
}
【讨论】:
我的代码让浏览器返回一页,如果失败,它会加载一个后备网址。它还检测主题标签的变化。
当后退按钮不可用时,后备 url 将在 500 毫秒后加载,因此浏览器有足够的时间加载上一页。在window.history.go(-1); 之后加载后备url 会导致浏览器使用后备url,因为js 脚本还没有停止。
function historyBackWFallback(fallbackUrl) {
fallbackUrl = fallbackUrl || '/';
var prevPage = window.location.href;
window.history.go(-1);
setTimeout(function(){
if (window.location.href == prevPage) {
window.location.href = fallbackUrl;
}
}, 500);
}
【讨论】:
chrome://newtab,因此您可以回到历史。
这就是我的做法。
我使用 'beforeunload' 事件 来设置布尔值。然后我设置了一个超时来观察'beforeunload'是否触发。
var $window = $(window),
$trigger = $('.select_your_link'),
fallback = 'your_fallback_url';
hasHistory = false;
$window.on('beforeunload', function(){
hasHistory = true;
});
$trigger.on('click', function(){
window.history.go(-1);
setTimeout(function(){
if (!hasHistory){
window.location.href = fallback;
}
}, 200);
return false;
});
似乎可以在主流浏览器中使用(目前已测试 FF、Chrome、IE11)。
【讨论】:
window.location.href = fallback 替换为window.close(),它也可以。
我在项目中使用了一个 sn-p:
function back(url) {
if (history.length > 2) {
// if history is not empty, go back:
window.History.back();
} else if (url) {
// go to specified fallback url:
window.History.replaceState(null, null, url);
} else {
// go home:
window.History.replaceState(null, null, '/');
}
}
仅供参考:我使用History.js 来管理浏览器历史记录。
为什么要将 history.length 与数字 2 进行比较?
因为 Chrome 的起始页被计为浏览器历史记录中的第一项。
history.length 和用户行为的可能性很小:
history.length = 2 并且在这种情况下我们要禁用 back(),因为用户将转到空白选项卡。history.length = 1 再次我们要禁用 back() 方法。history.length > 2 现在可以启用back()。注意:我省略了当用户在没有target="_blank"的情况下点击外部网站链接后进入当前页面的情况。
注意 2:document.referrer 在您通过输入其地址打开网站以及网站使用 ajax 加载子页面时为空,因此我在第一种情况下停止检查此值。
【讨论】:
这似乎可以解决问题:
function goBackOrClose() {
window.history.back();
window.close();
//or if you are not interested in closing the window, do something else here
//e.g.
theBrowserCantGoBack();
}
调用 history.back() 然后 window.close()。如果浏览器能够返回历史记录,它将无法进入下一条语句。如果无法返回,它将关闭窗口。
但是,请注意,如果通过输入 url 到达该页面,则 firefox 不会允许脚本关闭窗口。
【讨论】:
window.close() 被许多现代浏览器视为安全风险。有些人就是不让你这样做。
注意window.history.length,因为它还包含window.history.forward() 的条目
因此,您可能有超过 1 个条目的 window.history.length,但没有历史回溯条目。
这意味着如果你开火window.history.back()
【讨论】:
您不能直接检查后退按钮是否可用。您可以查看history.length>0,但如果当前页面也有ahead 页面,那将是正确的。只有当history.length===0 时,您才能确定后退按钮不可用。
如果这还不够好,您所能做的就是致电history.back(),如果之后您的页面仍在加载,则返回按钮不可用!当然,这意味着如果后退按钮 可用,则您刚刚离开该页面。你不能取消onunload 中的导航,所以你能做的就是阻止后面实际发生的所有事情就是从onbeforeunload 返回一些东西,这将导致出现一个大的烦人的提示。不值得。
事实上,对历史做任何事情通常都是一个非常糟糕的主意。历史导航适用于浏览器 chrome,而不是网页。添加“返回”链接通常会导致用户混淆而不是其价值。
【讨论】:
1! 0 是个脑残,我认为浏览器总是会回复 1 或更多。事实证明 Opera 和 IE 的想法不同——很好。
history.length 没有用,因为它没有显示用户是否可以回到历史。
不同的浏览器也使用初始值 0 或 1 - 这取决于浏览器。
有效的解决方案是使用$(window).on('beforeunload' 事件,但我不确定如果页面是通过 ajax 加载并使用 pushState 更改窗口历史记录,它是否会起作用。
所以我使用了下一个解决方案:
var currentUrl = window.location.href;
window.history.back();
setTimeout(function(){
// if location was not changed in 100 ms, then there is no history back
if(currentUrl === window.location.href){
// redirect to site root
window.location.href = '/';
}
}, 100);
【讨论】:
我想出了以下方法。它利用 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") 调用此函数。
【讨论】:
windows.onbeforeunload 更改为事件监听器window.addEventListener("beforeunload", function (event) { useFallback = false; });,所以它不会覆盖window.onbeforeunload。
还有一个接近完美的解决方案,取自another SO answer:
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 上对我有用。
【讨论】:
这对我使用 react 有效,但可以在另一种情况下工作;当历史记录在第一页时(您无法返回),window.history.status 将为空,因此如果您想知道是否可以返回,您只需要:
if (window.history.state == null) {
//you cannot go back
}
【讨论】:
浏览器有后退和前进按钮。我想出了这个问题的解决方案。但它会影响浏览器的转发操作并导致某些浏览器出现错误。
它的工作原理是这样的:如果浏览器打开一个从未打开过的新 url,history.length 将会增长。
这样你就可以改变散列
location.href = '#__transfer__' + new Date().getTime()
要获得一个从未显示的 url,那么 history.length 将获得真实的长度。
var realHistoryLength = history.length - 1
但是,它并不总是很好,我不知道为什么,尤其是当 url 自动快速跳转时。
【讨论】:
我试图找到一个解决方案,这是我能得到的最好的解决方案(但效果很好,甚至是我在这里找到的最简单的解决方案)。
就我而言,我想用后退按钮返回历史记录,但如果用户打开的第一个页面是我的应用程序的子页面,它将返回到主页面。
解决方案是,一旦加载应用程序,我就对历史状态进行了替换:
history.replaceState( {root: true}, '', window.location.pathname + window.location.hash)
这样,我只需要在返回之前检查history.state.root。如果为真,我会替换历史记录:
if(history.state && history.state.root)
history.replaceState( {root: true}, '', '/')
else
history.back()
【讨论】:
var func = function(){ console.log("do something"); };
if(document.referrer.includes(window.location.hostname) && history.length-1 <= 1){
func();
}
else{
const currentUrl = window.location.href;
history.back();
setTimeout(function(){
currentUrl === window.location.href && func();
}, 100);
}
【讨论】:
我在 Angular 中使用 window.history 来解决我网站上的常见问题。
当用户想要退出FAQ时,他们可以点击退出按钮(在返回按钮旁边)
我对这个“退出”策略的逻辑是基于入口 ID,然后返回到该状态的状态数。
所以输入:
enterState: { navigationId:number } = {navigationId: 1}
constructor() {
this.enterState = window.history.state
}
假装用户浏览了常见问题解答
然后,当用户单击退出按钮时,读取当前状态并计算您的增量:
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)
}
}
如您所见,我还使用了用户在常见问题解答中启动时的回退,在这种情况下,state.navigationId 是1,我们想要返回,替换第一个状态并显示主页(对于我使用的是 Angular 路由器,但您也可以在处理自己的路由时使用 history.replaceState)
供参考:
【讨论】:
window.history.length == 1
这适用于 Chrome、Firefox 和 Edge。 如果您想在没有窗口历史记录的情况下隐藏或删除已开发网页上的后退按钮,您可以在上述所有 3 个浏览器的最新版本上使用以下对我有用的 JQuery 代码。
$(window).load(function() {
if (window.history.length == 1) {
$("#back-button").remove();
}
})
【讨论】:
var fallbackUrl = "home.php";
if(history.back() === undefined)
window.location.href = fallbackUrl;
【讨论】:
history.back() 是 undefined 仅在空白标签页上
我正在使用一点 PHP 来实现结果。不过有点生锈了。但它应该可以工作。
<?php
function pref(){
return (isset($_SERVER['HTTP_REFERER'])) ? true : '';
}
?>
<html>
<body>
<input type="hidden" id="_pref" value="<?=pref()?>">
<button type="button" id="myButton">GoBack</button>
<!-- Include jquery library -->
<script>
if (!$('#_pref').val()) {
$('#myButton').hide() // or $('#myButton').remove()
}
</script>
</body>
</html>
【讨论】:
'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。有关详细信息,请参阅有关 window.location 的文档。
接下来,对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() 和 Destructuring assignment 的文档。
现在,如果用户在https://domain/ 上尝试返回,我们不会触发 if 语句,因此不会触发window.history.back() 方法,因此用户将留在我们的网站中。此 URL 将等效于长度为 0 的 [],而 0 > 0 为 false。因此,默默地失败了。当然,您可以根据需要记录一些内容或执行其他操作。
'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,此解决方案将不起作用。在使用此解决方案之前,请查看文档以了解更多信息。
【讨论】:
我不确定这是否有效并且它完全未经测试,但试试这个:
<script type="text/javascript">
function goBack() {
history.back();
}
if (history.length > 0) { //if there is a history...
document.getElementsByTagName('button')[].onclick="goBack()"; //assign function "goBack()" to all buttons onClick
} else {
die();
}
</script>
在 HTML 中的某处:
<button value="Button1"> //These buttons have no action
<button value="Button2">
您还可以做的是研究哪些浏览器支持返回功能(我认为它们都支持)并使用在this page 上找到并详细描述的标准 JavaScript 浏览器检测对象。然后你可以有 2 个不同的页面:一个用于与后退按钮兼容的“好浏览器”,一个用于“坏浏览器”,告诉他们去更新他们的浏览器
【讨论】:
history.back 是一个函数。你想检查history.length > 0 是否返回history.back()
[] 也没有任何意义,您不能将字符串分配给事件处理程序。
检查window.history.length是否等于0。
【讨论】: