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

匿名 (未验证) 提交于 2019-12-03 01:23:02

问题:

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

Declaration of back button

 

Button action:

 $("#verification_back_icon").on("click", function(e) { if(checkDirtyVacation()) {     e.preventDefault();     if(backbtnAlt== false)     {         backbtnAlt =true;           confirm("All data will be lost. Do you want to continue?",         function(r){             if(r){                  //onBackKeyDown();                     clearVacationvalues();                     window.history.back();//this is not working in iOS 9             }else{              }             backbtnAlt =false;         });     }    } else  {     e.preventDefault();     if($(".vaction_location").hasClass("chkSelect"))     {             $(".vaction_location").removeClass("chkSelect");         $(".vaction_location").addClass("chkUnSelect");     }       window.history.back();    }   });  

This worked perfectly till iOS 8.4. In iOS 9 this navigation is not working.

I am using Apache Cordova native platform version 3.8.0 .

If anyone facing the similar problem please suggest me. I have tried with history.back doesn't work on iOS using Cordova, but no luck

Thank you.

回答1:

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.



回答2:

Disabling push state worked for me:

$.mobile.pushStateEnabled = false;



回答3:

@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



回答4:

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

   

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];                     }*/ 


回答5:

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

back

  • javascript

    $('#back-btn').on('click', function(e) {        window.history.go(-1);        return false;     }) 


回答6:

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!