可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
back
回答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); } }