是否可以检测到用户通过使用浏览器中的历史后退按钮进入了页面?最好我想使用 angular.js 检测这个动作。
我不想使用角度路由。如果用户提交表单并在成功提交到服务器并重定向后,它也应该可以工作,如果用户使用浏览器的后退按钮返回表单也应该是可能的。
是否可以检测到用户通过使用浏览器中的历史后退按钮进入了页面?最好我想使用 angular.js 检测这个动作。
我不想使用角度路由。如果用户提交表单并在成功提交到服务器并重定向后,它也应该可以工作,如果用户使用浏览器的后退按钮返回表单也应该是可能的。
这是 Angular 的解决方案。
myApp.run(function($rootScope, $route, $location){
//Bind the `$locationChangeSuccess` event on the rootScope, so that we dont need to
//bind in induvidual controllers.
$rootScope.$on('$locationChangeSuccess', function() {
$rootScope.actualLocation = $location.path();
});
$rootScope.$watch(function () {return $location.path()}, function (newLocation, oldLocation) {
if($rootScope.actualLocation === newLocation) {
alert('Why did you use history back?');
}
});
});
我正在使用运行块来启动它。首先我将实际位置存储在 $rootScope.actualLocation 中,然后我听 $locationChangeSuccess 并且当它发生时我用新值更新 actualLocation。
在 $rootScope 中,我观察位置路径的变化,如果新位置等于 previousLocation 是因为 $locationChangeSuccess 没有被触发,这意味着用户已经使用了历史记录。
如果您想要更精确的解决方案(检测前后检测),我扩展了Bertrand提供的解决方案:
$rootScope.$on('$locationChangeSuccess', function() {
$rootScope.actualLocation = $location.path();
});
$rootScope.$watch(function () {return $location.path()}, function (newLocation, oldLocation) {
//true only for onPopState
if($rootScope.actualLocation === newLocation) {
var back,
historyState = $window.history.state;
back = !!(historyState && historyState.position <= $rootScope.stackPosition);
if (back) {
//back button
$rootScope.stackPosition--;
} else {
//forward button
$rootScope.stackPosition++;
}
} else {
//normal-way change of page (via link click)
if ($route.current) {
$window.history.replaceState({
position: $rootScope.stackPosition
});
$rootScope.stackPosition++;
}
}
});
对于 ui 路由,我使用以下代码。
在里面App.run()
,使用
$rootScope.$on("$stateChangeStart", function (event, toState, toParams, fromState, fromParams)
{
if (toState.name === $rootScope.previousState )
{
// u can any 1 or all of below 3 statements
event.preventDefault(); // to Disable the event
$state.go('someDefaultState'); //As some popular banking sites are using
alert("Back button Clicked");
}
else
$rootScope.previousState= fromState.name;
});
如果你愿意,你也可以在 '$stateChangeSuccess' 事件中获得 'previousState' 值,如下所示。
$rootScope.$on("$stateChangeSuccess", function (event, toState, toParams, fromState, fromParams)
{
$rootScope.previousStatus = fromState.name;
});
我知道这是一个老问题。无论如何 :)
Bema 的回答看起来很棒。但是,如果您想让它与“普通”网址一起使用(我猜没有哈希),您可以比较绝对路径,而不是由以下返回的路径$location.path()
:
myApp.run(function($rootScope, $route, $location){
//Bind the `$locationChangeSuccess` event on the rootScope, so that we dont need to
//bind in induvidual controllers.
$rootScope.$on('$locationChangeSuccess', function() {
$rootScope.actualLocation = $location.absUrl();
});
$rootScope.$watch(function () {return $location.absUrl()}, function (newLocation, oldLocation) {
if($rootScope.actualLocation === newLocation) {
alert('Why did you use history back?');
}
});
});
JavaScript 有一个本地历史对象。
window.history
查看 MDN 以获取更多信息;https://developer.mozilla.org/en-US/docs/DOM/window.history?redirectlocale=en-US&redirectslug=window.history
不确定它在多浏览器支持方面有多好。
更新
似乎我上面所说的仅适用于 Gecko 类型的浏览器。
对于其他浏览器尝试使用history.js
; https://github.com/browserstate/history.js