Как определить событие нажатия кнопки возврата браузера с помощью angular?
можно ли обнаружить, что пользователь вошел на страницу с помощью кнопки история назад в своем браузере? Предпочтительно я хочу обнаружить это действие с помощью углового.js.
Я не хочу использовать угловые маршрутизации. Он также должен работать, если пользователь отправляет форму и после успешной отправки на сервер и повторного направления, это также должно быть возможно, если пользователь возвращается к форме с помощью кнопки "Назад" браузера.
8 ответов:
вот решение с углового.
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 я наблюдаю за изменениями в пути местоположения, и если новое местоположение равно предыдущему местоположению, потому что $locationChangeSuccess не был запущен, то есть пользователь использовал история вернулась.
Если вы хотите более точное решение (обнаружение назад и вперед) я расширенное решение поставляется Бертран:
$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; });
вы можете получить значение "previousState" в событии "$stateChangeSuccess " также следующим образом, если хотите.
$rootScope.$on("$stateChangeSuccess", function (event, toState, toParams, fromState, fromParams) { $rootScope.previousStatus = fromState.name; });
Я знаю, это старый вопрос. В любом случае :)
ответ Бемы выглядит великолепно. Однако, если вы хотите, чтобы он работал с "нормальными" URL-адресами (без хэша, я думаю), вы можете сравнить абсолютный путь, а не тот, который возвращается
$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
Итак, я переписал ответ @Bema в TypeScript, и вот как это выглядит:
namespace MyAwesomeApp { // ReSharper disable once Class function detectBackButton( $rootScope: ng.IRootScopeService, $location: ng.ILocationService ) { let actualLocation: string = ''; $rootScope.$on('$locationChangeSuccess', () => { actualLocation = $location.path(); }); $rootScope.$watch(() => $location.path(), (newLocation: string, oldLocation: string) => { if (actualLocation === newLocation) { //$rootScope.$broadcast('onBackButtonPressed', null); } }); } detectBackButton.$inject = [ '$rootScope', '$location' ]; angular .module('app') .run(detectBackButton); }
нам не нужно создавать свойство от
$rootScope
сервис, мы можем просто иметь наш "на месте изменения успеха" и "на месте изменения" код как закрыть над локальнымactualLocation
переменной. Оттуда вы можете делать все, что угодно, как и в исходном коде. Со своей стороны, я бы рассмотрел трансляцию события, чтобы отдельные контроллеры могли делать все, что они должны, но вы можете включить глобальные действия если вы.Спасибо за отличный ответ, и я надеюсь, что это поможет другим пользователям typescript там.
мое решение этой проблемы
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(); }); });