Как определить событие щелчка кнопки "Назад" с помощью angular?

Можно ли обнаружить, что пользователь ввел страницу с помощью кнопки возврата назад в своем браузере? Предпочтительно, я хочу обнаружить это действие, используя angular.js.

Я не хочу использовать маршрутизацию angular. Он также должен работать, если пользователь отправляет форму и после успешной отправки на сервер и перенаправки также должен быть возможен, если пользователь вернется к форме с помощью кнопки "Назад" браузера.

Ответ 1

Вот решение с 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 я наблюдаю за изменениями в пути к местоположению, и если новое местоположение равно предыдущему, это потому, что $locationChangeSuccess не был запущен, то есть пользователь использовал историю назад.

Ответ 2

Если вам нужно более точное решение (обнаружение назад и вперед), я расширил решение, предоставленное 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++;

        }

    }

 });

Ответ 3

Для ui-routing я использую приведенный ниже код.

Внутри 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;
    });

Ответ 4

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

Ответ 5

Я знаю, что это старый вопрос. В любом случае:)

Ответ Бема выглядит великолепно. Однако, если вы хотите заставить его работать с "нормальными" 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?');
        }
    });
});

Ответ 6

Мой Solutio для этой проблемы

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();
    });
});

Ответ 7

при нажатии кнопки angular срабатывает только $routeChangeStart событие, $locationChangeStart не запускается.