检测是否在JavaScript中的WKWebView内加载了页面

时间:2015-03-01 15:44:24

标签: javascript ios uiwebview mobile-safari wkwebview

如何使用javascript可靠地检测到WKWebView中是否加载了页面?我希望能够检测到这些情况:

  • iOS& WKWebView
  • iOS& Safari浏览器
  • 不是iOS

有关于UIWebView here的类似问题。但它已经很老了,我不确定它是否仍适用于WKWebView。

5 个答案:

答案 0 :(得分:28)

使用WKWebView vs UIWebView app

测试后,接受的答案无效

正如文章所提到的,唯一的HTML5功能差异是IndexedDB支持。因此,我会寻求更可靠的模式:

    if (navigator.platform.substr(0,2) === 'iP'){
      //iOS (iPhone, iPod or iPad)
      var lte9 = /constructor/i.test(window.HTMLElement);
      var nav = window.navigator, ua = nav.userAgent, idb = !!window.indexedDB;
      if (ua.indexOf('Safari') !== -1 && ua.indexOf('Version') !== -1 && !nav.standalone){      
        //Safari (WKWebView/Nitro since 6+)
      } else if ((!idb && lte9) || !window.statusbar.visible) {
        //UIWebView
      } else if ((window.webkit && window.webkit.messageHandlers) || !lte9 || idb){
        //WKWebView
      }
    }

您可能会问:为什么不使用UserAgent?这是因为Android浏览器将其用作设置!所以,我们永远不要相信任何UA。只有浏览器功能和属性检查。

另外我注意到QuickTime插件总是作为旧版Safari和UIWebView中的其他浏览器的一部分加载。但是WKWebView中不再存在该插件。因此,您可以使用QuickTime插件作为额外检查。

9/23/16编辑:我调整了Safari 10的代码,不再允许唯一的idb检查是可靠的,如@xmnboy所述。要丢弃Safari 10,它会检查旧的webkit引擎错误,该错误仅适用于Safari 9.2;在iOS 9和10之间进行了一些比较测试后,我使用了window.statusbar.visible后备,这似乎是一个可靠的指示信号。(请检查)

答案 1 :(得分:4)

鉴于Apple在iOS 10中引入的UIWebView的行为发生了变化,这里结合了@ Justin-Michael的原始响应和@hexalys的后续收藏。

var isWKWebView = false ;
if( navigator.platform.substr(0,2) === 'iP' ) {    // iOS detected
    if( window.webkit && window.webkit.messageHandlers ) {
        isWKWebView = true ;
    }
}

事实证明,Justin的答案确实是更好的功能检测机制,因为它适用于iOS 9和iOS 10。

不知道当我们进入iOS 11时会发生什么: - )

资格认证:如果您使用official Cordova WKWebView plugin构建网络视图应用,此测试将有效,因为该插件会初始化addScriptMessageHandler方法,如@hexalys所述在这篇文章的评论中。当存在WKWebView插件时,Cordova正在使用该机制来定义新的 JS到本机桥

that plugin repo中搜索addScriptMessageHandler,并查看该回购中the ios-wkwebview-exec.js file的最后部分,了解一些实施细节(或在该文件中搜索字符串window.webkit.messageHandlers)。

答案 2 :(得分:0)

似乎由于使用WKWebView作为渲染引擎的最新iOS Chrome,Chrome被检测为WKWebView。 ua.indexOf('CriOS')!== -1将有助于区分Chrome和应用程序中的WKWebView。

答案 3 :(得分:0)

在iOS中,您可以添加此代码以在javascript和objective-c之间建立通信:

WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
WKUserContentController *controller = [[WKUserContentController alloc] init];
[controller addScriptMessageHandler:self name:@"javascript_observer"];
configuration.userContentController = controller;

...

webview = [[WKWebView alloc] initWithFrame:... configuration: configuration];

在javascript中,您可以像这样测试连接:

if ( window.webkit != undefined ){
//javascript is running in webview
}

答案 4 :(得分:-3)

您可以检查WKWebKit用于从JavaScript接收消息的window.webkit.messageHandlers是否存在。如果它存在,您就在WKWebView内。

结合简单的用户代理检查应该可以解决问题:

var iOS = (navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false);
var isWKWebView = false;
if (window.webkit && window.webkit.messageHandlers) {
    isWKWebView = true;
}