कोणीय का उपयोग करके ब्राउज़र बैक बटन क्लिक इवेंट का पता कैसे लगाएं?


79

क्या यह पता लगाना संभव है कि किसी उपयोगकर्ता ने अपने ब्राउज़र में इतिहास बैक बटन का उपयोग करके एक पृष्ठ दर्ज किया? अधिमानतः मैं कोणीय.जेएस का उपयोग करके इस कार्रवाई का पता लगाना चाहता हूं।

मैं कोणीय मार्ग का उपयोग नहीं करना चाहता। यह तब भी काम करना चाहिए जब कोई उपयोगकर्ता किसी प्रपत्र को सबमिट करता है और सर्वर को एक सफल सबमिट करने के बाद और फिर से प्रत्यक्ष होता है, यह भी संभव होना चाहिए यदि उपयोगकर्ता ब्राउज़र के बैक बटन का उपयोग करके फॉर्म में वापस जाता है।

जवाबों:


120

यहां पर कोणीय के साथ एक समाधान है।

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 को सुनता हूं और जब ऐसा होता है तो मैं वास्तविक मान को नए मूल्य के साथ अद्यतन करता हूं।

$ RootScope में मैं स्थान पथ में परिवर्तन के लिए देखता हूं और यदि नया स्थान पिछले स्थान के बराबर है, क्योंकि $ स्थान स्थान परिवर्तन असफल नहीं हुआ था, जिसका अर्थ है कि उपयोगकर्ता ने इतिहास का वापस उपयोग किया है।


1
धन्यवाद! अच्छा लग रहा है। कल इसकी विस्तार से जाँच करनी है। विशेष रूप से मुझे यह जांचना होगा कि क्या $ rootScope.actualLocation को भी अपडेट किया गया है यदि स्थान कोणीय मार्गों का उपयोग किए बिना बदल दिया जाता है, लेकिन "सामान्य" हाइपरलिंक। क्या आपको लगता है कि यह सामान्य हाइपरलिंक का उपयोग करके भी काम करेगा?
थॉमस क्रेम्मेल

4
आह येस। पहले कभी भी कोणीय मार्गों का उपयोग नहीं किया गया था, इसलिए आपके उदाहरण को देखकर ऐसा लगता है कि कोई सामान्य और सामान्य नहीं हैं (कोणीय मार्ग प्रकार) हाइपरलिंक। तो बस मेरी टिप्पणी भूल जाओ ..
थॉमस Kremmel

2
$ LocationProvider.html5Mode (true) का उपयोग केवल jsField में लिंक का काम करने के लिए किया जाता है, आपको इसे अपने प्रोजेक्ट में आवश्यकता नहीं होगी। बस याद रखें कि लिंक को # / से पहले करने की आवश्यकता है ताकि कोणीय उन्हें पकड़ सकें (फिडल में वे नहीं हैं)। यदि आप "सामान्य" लिंक का उपयोग करते हैं, तो कुछ / जैसे पुस्तक, कोणीय इसे कैप्चर नहीं करेंगे और पृष्ठ को उस url पर पुनर्निर्देशित किया जाएगा, इससे आपका ऐप रीसेट हो जाएगा क्योंकि सभी स्क्रिप्ट पुनः लोड हो जाएंगे, इसीलिए यह काम नहीं करेगा ।
बर्ट्रेंड

19
किसी के लिए (मेरे जैसे) जो यह नहीं समझते कि यह कैसे काम करता है: जब url सामान्य तरीके से बदल रहा है (बैक / फॉरवर्ड बटन का उपयोग नहीं कर रहा है), तो कॉलबैक के बाद$locationChangeSuccess इवेंट फायरिंग । लेकिन जब url बैक / फॉरवर्ड बटन या एपीआई का उपयोग करके बदल रहा है , तो कॉलबैक से पहले इवेंट फायरिंग करें । तो जब देखो कॉलबैक फायरिंग पहले से ही बराबर है । यह सिर्फ यह है कि कोणीय आंतरिक रूप से कैसे काम करता है और यह समाधान सिर्फ इस आंतरिक व्यवहार का उपयोग करता है। $watchhistory.back()$locationChangeSuccess $watchactualLocationnewLocation
रुस्लान Stelmachenko

5
कोड ऊपर URL क्वेरी स्ट्रिंग परिवर्तन का पता लगाने नहीं करता है, से की तरह /#/news/?page=2करने के लिए /#/news/?page=3। उन लोगों को भी पकड़ने के लिए आप (दोनों स्थानों पर जहां इसका ऊपर उपयोग किया गया है) के $location.absUrl()बजाय उपयोग कर सकते $location.path()हैं।
माइकल

11

यदि आप अधिक सटीक समाधान चाहते हैं (वापस और आगे का पता लगाते हुए) मैंने बर्ट्रेंड द्वारा दिया गया समाधान बढ़ाया :

$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++;

        }

    }

 });

8

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' ईवेंट में 'पूर्ववर्ती' मान प्राप्त कर सकते हैं, जैसे कि यदि आप चाहें तो निम्नानुसार हैं।

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

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

यह बैक बटन क्लिक का पता नहीं लगाता है - यह पता लगाता है कि उपयोगकर्ता दो राज्य नामों के बीच टॉगल कर रहा है - या तो बैक बटन के माध्यम से, या दो पृष्ठों के बीच क्लिक करके। इसके अलावा, यह राज्य के परम में नहीं दिखता है।
एमी बी

1

मुझे पता है कि यह एक पुराना सवाल है। वैसे भी :)

बेमा का जवाब बहुत अच्छा लग रहा है। हालाँकि, यदि आप इसे 'सामान्य' यूआरएल के साथ काम करना चाहते हैं (हैश के बिना मुझे लगता है), तो आप इसके बजाय पूर्ण पथ की तुलना कर सकते हैं $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?');
        }
    });
});

0

जावास्क्रिप्ट में एक देशी इतिहास वस्तु है।

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

इसलिए, मैंने @ टाइप करके उत्तर टाइपस्क्रिप्ट में ट्रांसफ़र किया है, और यह ऐसा दिखता है:

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। वहां से, आप जो चाहें, जैसे मूल कोड में कर सकते हैं। अपने हिस्से के लिए, मैं एक ईवेंट प्रसारित करने पर विचार करूंगा ताकि व्यक्तिगत नियंत्रक जो कुछ भी कर सकते हैं, वह कर सकें, लेकिन यदि आप करना चाहते थे, तो आप वैश्विक कार्यों को शामिल कर सकते हैं ।

महान जवाब के लिए धन्यवाद, और मुझे उम्मीद है कि इससे अन्य टाइपस्क्रिप्ट उपयोगकर्ताओं को मदद मिलेगी।


-2

इस समस्या के लिए मेरा 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

जब बैक बटन दबाते हैं, तो कोणीय केवल $ मार्ग परिवर्तन की घटना, $ स्थान बदल देती है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.