javascript Cordova - window.history.back() 不适用于 iOS 9 中的 HTML 后退按钮

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32761206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 15:43:59  来源:igfitidea点击:

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

javascripthtmlcordovaios9cordova-3.8.0

提问by soumya

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

在我的应用程序中,我使用window.history.back导航回上一个视图

Declaration of back button

后退按钮声明

 <div class="back_icon"  id="verification_back_icon"><a href="#" data-rel="back"  data-transition="slidedown"><img src="images/back_btn.png" width="23"/></a></div>

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.

这在 iOS 8.4 之前一直有效。在 iOS 9 中,此导航不起作用。

I am using Apache Cordova native platform version 3.8.0.

我正在使用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

如果有人面临类似的问题,请建议我。我尝试过history.back 在使用 Cordova 的 iOS 上不起作用,但没有运气

Thank you.

谢谢你。

采纳答案by soumya

SOLUTION:

解决方案:

This line resolved my issue :

这一行解决了我的问题:

 history.go(0); 

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

我已经替换 window.history.back()history.go(0);

Now it is working fine for me in iOS 9

现在它在 iOS 9 中对我来说很好用

In index.html

在 index.html

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

Add this in onDeviceReady function:

在 onDeviceReady 函数中添加:

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

设备操作系统版本验证(history.go(0)仅适用于 iOS 9) 在 iOS 9 版本之前 window.history.back()完美运行

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

现在添加这段代码代替 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

要修复此消息“无法加载网页并出现错误:CDVWebViewDelegate:当 state=1 时导航开始”在控制台中添加以下代码在CDVWebViewDelegate.m

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

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

回答by DaveAlden

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

问题是window.location.hash在 iOS 9.0 UIWebview(由 Cordova/Phonegap 使用)中的设置是异步的 -有关详细信息,请参阅此错误报告

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

这会导致使用 jQuery Mobile 时出现问题,默认情况下它window.location.hash用于在“页面”之间导航。它还会导致使用此机制的弹出窗口/对话框/选择菜单出现问题。

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

您可以通过阻止 jQuery Mobile 自动侦听/使用 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:

但是,我发现这对 Android 有副作用,例如导致硬件后退按钮不起作用,因此我使用cordova-plugin-device专门针对 iOS 9 :

$(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.

请注意,我navigator.app.backHistory()window.history.back()结合使用hashListeningEnabled = false- 这可能会有所作为。

Alternatively you can use this pluginto 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 bugin WKWebView in iOS 8, but the upcoming cordova-ios 4 will supporta WKWebView core pluginfor 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.

或者,您可以使用此插件在 iOS 8 和 9 上使用新的 WKWebView。iOS 8+ 上的 Safari 使用 WKWebView,因此在 iOS 9 上的浏览​​器中查看 JQM 站点不会遇到这些问题。由于iOS 8 中 WKWebView的错误,cordova-ios 3 仍然使用 UIWebView ,但即将推出的cordova-ios 4将支持适用于 iOS 9+的WKWebView 核心插件。请注意,由于其更严格的安全性,在将 WKWebView 与 Cordova/Phonegap 应用程序一起使用时还有其他注意事项,例如要求 XHR 响应上的 CORS 标头。

回答by dannyliu

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

我认为是 A 标签的默认操作导致了该错误。所以我只是通过return false在点击处理函数的末尾添加来阻止默认操作

And it works.

它有效。

  • html
  • html

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

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

  • javascript

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

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

回答by Ian Drake

Disabling push state worked for me:

禁用推送状态对我有用:

$.mobile.pushStateEnabled = false;

$.mobile.pushStateEnabled = false;

回答by JesseMonroy650

@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 团队的说法,iOS9 尚未得到官方支持。此问题可能是 iOS9 中的另一个错误。您可能需要等待修复。

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

PhoneGap Build iOS 9 支持状态
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.

顶线:直到 Cordova-iOS 4.0.0 才正式支持 iOS 9,Cordova 团队正在努力工作。然而,一些问题可以通过一些简单的配置更改来解决。

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.

此时,有 4 个错误报告给 Cordova 错误存储库。您的问题未出现在存储库中 - 截至此日期。

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

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

回答by sunil

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