2013-04-04 45 views
69

是否有可能通过使用浏览器中的历史记录按钮来检测用户是否进入了页面?最好我想用angular.js检测这个动作。如何使用角度检测浏览器后退按钮单击事件?

我不想使用角度路由。如果用户提交表单,并且在成功提交给服务器并重定向之后,应该也可以工作,如果用户使用浏览器的后退按钮返回到表单,也应该是可能的。

回答

108

以下是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未被触发,这意味着用户已使用历史记录。

+1

谢谢!看起来很棒。必须明天详细检查它。特别是我必须检查$ rootScope.actualLocation是否也更新如果位置更改不使用角度路线,但“正常”的超链接。你认为它也可以使用普通的超链接吗? –

+1

“”正常“超链接”是什么意思? – Bema

+4

啊是的。以前从未使用过角度路线,所以看看你的例子,似乎没有正常的和不正常的(角度路线类型)超链接。所以只是忘了我的评论.. –

0

JavaScript有一个本机历史对象。

window.history 

查看MDN获取更多信息; https://developer.mozilla.org/en-US/docs/DOM/window.history?redirectlocale=en-US&redirectslug=window.history

不知道它在多浏览器支持寿上有多好。

更新

似乎什么我上面叫仅供壁虎式的浏览器。

对于其他浏览器尝试使用history.js; https://github.com/browserstate/history.js

+0

感谢您的评论。因为我更喜欢用角度来做这件事,所以我会给Bertrands一个答案。 –

-7

按下后退按钮时,角火灾只$ routeChangeStart事件,$ locationChangeStart没有被解雇。

9

如果你想更精确的解决方案(检测前进和后退)我延长了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++; 

     } 

    } 

}); 
0

我知道这是一个老问题。无论如何:)

贝玛的答案看起来不错。但是,如果你想使之与“正常”的网址的工作(不散列我猜的),你可以比较,而不是由$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?'); 
     } 
    }); 
}); 
-2

我的搜索解决方案这个问题是

app.run(function($rootScope, $location) { 
    $rootScope.$on('$locationChangeSuccess', function() { 
     if($rootScope.previousLocation == $location.path()) { 
      console.log("Back Button Pressed"); 
     } 
     $rootScope.previousLocation = $rootScope.actualLocation; 
     $rootScope.actualLocation = $location.path(); 
    }); 
}); 
5

对于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; 
    }); 
+0

正是我在找的东西。非常感谢。 –

+0

这不检测返回按钮的点击 - 这只是检测用户是在两个国家名称之间切换 - ei也可以通过后退按钮,或通过在两页之间点击。这也不看国家的参数。 –

相关问题