Cordova - window.history.back() not working on HTML back button in iOS 9

前端 未结 6 1558
失恋的感觉
失恋的感觉 2020-12-05 21:48

In my application I am using window.history.back to navigate back to previous View

Declaration of back button

 <         


        
相关标签:
6条回答
  • 2020-12-05 22:11

    I think it is the A tag's default action causes the bug. So I just prevent the default action by adding return false at end of the click handler function

    And it works.

    • html

    <a id="back-btn">back</a>

    • javascript

      $('#back-btn').on('click', function(e) {
             window.history.go(-1);
             return false;
          })
      
    0 讨论(0)
  • 2020-12-05 22:17

    @Sujania,

    According to the phonegap team, iOS9 is not officially support. This issue may be yet another bug in iOS9. You may have to wait for a fix.

    PhoneGap Build iOS 9 Support Status
    http://community.phonegap.com/nitobi/topics/phonegap-build-ios-9-support-status

    Top line: iOS 9 is not officially supported until Cordova-iOS 4.0.0, which the Cordova team is hard at work on. However some issues can be solved with some simple configuration changes.

    At this point in time, 4 bugs are reported to the Cordova Bug repository. Your issue does not appear in the respository - as of this date.

    https://issues.apache.org/jira/browse/CB-9684?jql=text%20~%20%22iOS9%22

    0 讨论(0)
  • 2020-12-05 22:24

    The problem is that setting of window.location.hash is asynchronous in the iOS 9.0 UIWebview (used by Cordova/Phonegap) - see this bug report for details.

    This causes issues when using jQuery Mobile which by default uses window.location.hash to navigate between "pages". It also causes issues with popups/dialogs/select menus which use this mechanism.

    You can fix this by preventing jQuery Mobile from automatically listening/using location.hash:

    $(document).on("deviceready", function(){
        $.mobile.hashListeningEnabled = false;
    });
    

    However, I found this had side effects on Android such as causing the hardware back button not to work, so I targeted it specifically at iOS 9 using cordova-plugin-device:

    $(document).on("deviceready", function(){
        if(device.platform === "iOS" && parseInt(device.version) === 9){
            $.mobile.hashListeningEnabled = false;
        }
    });
    

    Note that I'm using navigator.app.backHistory() not window.history.back() in conjunction with hashListeningEnabled = false - this may make a difference.

    Alternatively you can use this plugin to use the new WKWebView on iOS 8 and 9. WKWebView is used by Safari on iOS 8+, hence JQM sites viewed in the browser on iOS 9 don't encounter these issues. cordova-ios 3 still uses UIWebView due to a bug in WKWebView in iOS 8, but the upcoming cordova-ios 4 will support a WKWebView core plugin for iOS 9+. Note that there are additional considerations when using WKWebView with Cordova/Phonegap apps due to its stricter security, such as requiring CORS headers on XHR responses.

    0 讨论(0)
  • 2020-12-05 22:27

    Disabling push state worked for me:

    $.mobile.pushStateEnabled = false;

    0 讨论(0)
  • 2020-12-05 22:31

    SOLUTION:

    This line resolved my issue :

     history.go(0); 
    

    I have replaced window.history.back() with history.go(0);

    Now it is working fine for me in iOS 9

    In index.html

       <script type="text/javascript">$.mobile.hashListeningEnabled = false;</script>
    

    Add this in onDeviceReady function:

    function onDeviceReady() {
        if ( device.platform === "iOS" && parseInt( device.version ) === 9 ) {
            $.mobile.hashListeningEnabled = false;
        }
    
        if ( !( $.mobile.hashListeningEnabled &&
            $.mobile.path.isHashValid( location.hash ) &&
            ( $( hashPage ).is( ":jqmData(role='page')" ) ||
                $.mobile.path.isPath( hash ) ||
                hash === $.mobile.dialogHashKey ) ) ) {
    
            // make sure to set initial popstate state if it exists
            // so that navigation back to the initial page works properly
            if ( $.event.special.navigate.isPushStateEnabled() ) {
                $.mobile.navigate.navigator.squash( path.parseLocation().href );
            }
    
            $.mobile.changePage( $.mobile.firstPage, {
                transition: "none",
                reverse: true,
                changeHash: false,
                fromHashChange: true
            } );
        } else {
            // trigger hashchange or navigate to squash and record the correct
            // history entry for an initial hash path
            if ( !$.event.special.navigate.isPushStateEnabled() ) {
                $window.trigger( "hashchange", [true] );
            } else {
                // TODO figure out how to simplify this interaction with the initial history entry
                // at the bottom js/navigate/navigate.js
                $.mobile.navigate.history.stack = [];
                $.mobile.navigate( $.mobile.path.isPath( location.hash ) ? location.hash : location.href );
            }
        }
    }
    

    Validation for device OS version (as history.go(0) is working only with iOS 9) Prior to iOS 9 version window.history.back() working perfectly

    And now Add this piece of code in place of window.history.back()

    if ( device.platform === "iOS" && parseInt( device.version ) === 9 ) {
        console.log( "version" + device.version );
        console.log( "iOS 9" );
        history.go( 0 );
        //write your code here                 
    }
    else {
        window.history.back();
    }
    

    To fix this Message "Failed to load webpage with error: CDVWebViewDelegate: Navigation started when state=1" in console add below code in CDVWebViewDelegate.m

    In - (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType

    Method Comment this piece of code shown below:

    /*if ([_delegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) {
        NSDictionary* errorDictionary = @{NSLocalizedDescriptionKey : description};
        NSError* error = [[NSError alloc] initWithDomain:@"CDVWebViewDelegate" code:1 userInfo:errorDictionary];
        [_delegate webView:webView didFailLoadWithError:error];
    }*/
    
    0 讨论(0)
  • 2020-12-05 22:31

    Try this

    if(r){
             try{
              var nav = window.navigator;
              if( this.phonegapNavigationEnabled && nav && nav.app && nav.app.backHistory )
              {
                nav.app.backHistory();
              }
              else 
              {
                window.history.back();
              }
            }
            catch(e)
            {
             alert(e);
            }
          }
    
    0 讨论(0)
提交回复
热议问题