【问题标题】:Cordova - window.history.back() not working on HTML back button in iOS 9Cordova - window.history.back() 在 iOS 9 中的 HTML 后退按钮上不起作用
【发布时间】:2015-12-22 01:09:18
【问题描述】:

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

后退按钮声明

 <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>

按钮操作:

$( "#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();
    }
} );

这在 iOS 8.4 之前运行良好。在 iOS 9 中,此导航不起作用。

我正在使用Apache Cordova native platform version 3.8.0

如果有人遇到类似问题,请建议我。 我试过history.back doesn't work on iOS using Cordova,但没有运气

谢谢。

【问题讨论】:

  • 如果您的“上一个视图”使用哈希,那么您的问题可能是由于 window.location.hash 的设置是异步的 iOS 9 UIWebView - see here。如果没有更多关于您正在使用的框架的详细信息,很难知道......
  • @DaveAlden ..谢谢您的回复..请查看我更新的问题
  • 从您的 html sn-p 看,您可能正在使用 jQuery mobile?如果有,是什么版本?如果不是,请举例说明如何在视图之间导航
  • 是的,我使用的是 Jquery 移动版:jQuery Mobile 1.4.5 @daveAlden

标签: javascript html cordova ios9 cordova-3.8.0


【解决方案1】:

问题在于 window.location.hash 的设置在 iOS 9.0 UIWebview 中是异步的(由 Cordova/Phonegap 使用) - 请参阅 this bug report 了解详细信息。

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

您可以通过阻止 jQuery Mobile 自动侦听/使用 location.hash 来解决此问题:

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

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

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

请注意,我使用的是 navigator.app.backHistory() 而不是 window.history.back()hashListeningEnabled = false - 这可能会有所不同。

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

【讨论】:

  • 使用 $.mobile.hashListeningEnabled = false;在 ondeviceReady 方法中,导航点击不起作用。早些时候,无论向前导航点击次数如何,它都会弹回加载页面。
  • 如果这不起作用,WKWebView 可能是更好的选择
  • 我应该在界面生成器中用 WKWebView 替换 UIWebView 吗?我会尝试一次..
  • 不知道您是如何构建它的(本地或云服务),但是可以尝试看看 WKWebView 是否解决了这些问题。如果您使用 WKWebView,请务必进行良好的回归测试,因为它可能会导致其他问题。
  • 你知道如何在 mainViewController 中使用 WKWebView 代替 UIWebview 吗(我这里是 - (void)webViewDidFinishLoad:(UIWebView*)theWebView )
【解决方案2】:

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

而且有效。

  • html

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

  • javascript

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

【讨论】:

  • 我尝试了多种变体,这个对我有用。只需添加一个 [return false;] 就可以了。
【解决方案3】:

禁用推送状态对我有用:

$.mobile.pushStateEnabled = false;

【讨论】:

  • @lan Drake 与我的解决方案不同,这真的很好用。这没有给出任何“状态 =1 时开始导航”的问题。谢谢您的解决方案。
  • 通过上述方式禁用pushState后,我可以使用“navigator.app.backHistory()”返回吗?
【解决方案4】:

解决方案:

这一行解决了我的问题:

 history.go(0); 

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

现在它在 iOS 9 中对我来说工作正常

在 index.html 中

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

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

验证设备操作系统版本(history.go(0) 仅适用于 iOS 9)iOS 9 之前的版本 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();
}

要在控制台中修复此消息“无法加载网页并出现错误:CDVWebViewDelegate: Navigation started when state=1”,请在 CDVWebViewDelegate.m

中添加以下代码

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

方法注释这段代码如下所示:

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

【讨论】:

  • 导航工作正常,当我在控制台中得到这一行时:CDVWebViewDelegate: Navigation started when state=1 Failed to load pages with error: CDVWebViewDelegate: Navigation started when state=1
  • 有谁知道这种行为是小问题还是大问题?
【解决方案5】:

@Sujania,

根据 phonegap 团队的说法,iOS9 并未得到官方支持。这个问题可能是 iOS9 中的又一个 bug。您可能需要等待修复。

PhoneGap Build iOS 9 支持状态
http://community.phonegap.com/nitobi/topics/phonegap-build-ios-9-support-status

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

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

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

【讨论】:

  • 不管您使用的是什么,正如论坛帖子所述,直到 Cordova-iOS 4.0.0 才正式支持 iOS 9。这意味着,创建一个解决方法,或者等到它得到官方支持。 OR 向cordova 提交错误报告。 等到其他人创建解决方法。就我而言,我不在前沿工作,所以我是错误的跟进人。 --祝你好运。
【解决方案6】:

试试这个

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

【讨论】:

  • 感谢您的回复..但仍然是同样的问题..我的视图没有正确弹出
猜你喜欢
  • 2014-06-10
  • 1970-01-01
  • 2018-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-10
  • 1970-01-01
相关资源
最近更新 更多