your programing

각도를 사용하여 브라우저 뒤로 버튼 클릭 이벤트를 감지하는 방법은 무엇입니까?

lovepro 2020. 10. 12. 07:57
반응형

각도를 사용하여 브라우저 뒤로 버튼 클릭 이벤트를 감지하는 방법은 무엇입니까?


사용자가 브라우저의 히스토리 뒤로 버튼을 사용하여 페이지에 들어온 것을 감지 할 수 있습니까? 바람직하게는 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-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;
   });

원하면 다음과 같이 '$ stateChangeSuccess'이벤트에서 'previousState'값을 얻을 수 있습니다.

    $rootScope.$on("$stateChangeSuccess", function (event, toState, toParams, fromState, fromParams) 
   {

        $rootScope.previousStatus = fromState.name;
    });

나는 그것이 오래된 질문이라는 것을 압니다. 어쨌든 :)

Bema의 대답은 훌륭해 보입니다. 그러나 '정상적인'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

Check the MDN for more info; https://developer.mozilla.org/en-US/docs/DOM/window.history?redirectlocale=en-US&redirectslug=window.history

Not sure how good it's on multi-browser support tho.

Update

Seems what I've called above is only for Gecko-type browsers.

For other browsers try to use history.js; https://github.com/browserstate/history.js


So, I've transcribed the answer by @Bema into TypeScript, and this is what it looks like:

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

We don't have to create a property off of the $rootScope service, we can just have our 'on location change success' and 'on location changed' code both close over the local actualLocation variable. From there, you can do whatever you like, just as in the original code. For my part, I'd consider broadcasting an event so that individual controllers can do whatever they must, but you could include global actions if you had to.

Thanks for the great answer, and I hope this helps other typescript users out there.


My Solutio to this problem is

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

when pressing back button, angular fires only $routeChangeStart event, $locationChangeStart not fired.

참고URL : https://stackoverflow.com/questions/15813850/how-to-detect-browser-back-button-click-event-using-angular

반응형