Как определить событие нажатия кнопки возврата браузера с помощью angular?


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

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

8 73

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

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