检测页面是否在JavaScript中的WKWebView中加载
我怎样才能可靠地检测使用JavaScript,一个页面加载在一个WKWebView? 我希望能够检测到这些情况:
- iOS和WKWebView
- iOS和Safari
- 不是iOS
这里有一个关于UIWebView的类似问题。 但是这是相当古老的,我不确定是否仍然适用于WKWebView。
您可以检查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; }
接受的答案不工作,使用WKWebView与UIWebView应用程序进行testing
正如文章所提到的,唯一的HTML5特性差异是IndexedDB的支持。 所以我会select一个更可靠的模式:
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。 只有浏览器function和属性检查。
另外我注意到, QuickTime
插件总是作为UIWebView中的旧Safari和其他浏览器的一部分加载。 但是这个插件在WKWebView中不再存在。 所以你可以使用QuickTime
插件作为额外的检查。
9/23/16编辑:我调整了Safari 10的代码,不再允许唯一的IDB检查是可靠的,如@ xmnboy所述。 为了放弃Safari 10,它会检查旧的webkit引擎错误,这个错误只会在Safari 9.2之前被应用。 我使用了一个window.statusbar.visible
后备这似乎是一个可靠的指标信号后,iOS 9和10之间的几个比较testing(请检查虽然)
考虑到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 ; } }
事实certificate,Justin的答案确实是更好的function检测机制,因为它适用于iOS 9和iOS 10。
不知道当我们到了iOS 11时会发生什么::)
资格:如果您使用官方的Cordova WKWebView插件来构build您的webview应用程序,则此testing将起作用,因为该插件会初始化addScriptMessageHandler
方法,正如本文的评论中的@hexalys所述。 当WKWebView插件出现时,Cordova正在使用该机制来定义一个新的JS到本地桥接器 。
在该插件 addScriptMessageHandler
中searchaddScriptMessageHandler
,并查看该addScriptMessageHandler
中ios-wkwebview-exec.js
文件的最后一部分实现细节(或者在该文件中searchstringwindow.webkit.messageHandlers
)。
看来,由于最新的iOS Chrome使用WKWebView作为渲染引擎,因此Chrome被检测为WKWebView。 ua.indexOf('CriOS')!== -1将有助于在应用程序中区分Chrome和WKWebView。
在iOS中,您可以添加以下代码来build立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中,你可以像这样testing连接:
if ( window.webkit != undefined ){ //javascript is running in webview }
- 使用UIDocumentPickerViewController,可以像在Slack中一样打开默认服务(Dropbox,Google Drive等)吗?
- 斯威夫特:如何使我的angular色在我的游戏中只能在他击中地面时跳跃?
- UIActionSheet从子视图控制器显示iPad崩溃
- Swift + Objective-C项目应该如何设置unit testing
- 将定制属性添加到MKAnnotation
- UISearchBar解雇后resize
- 目标c中的音频文件格式问题
- iOS 9:推送/stream行视图控制器由edgesForExtendedLayout中断
- Swift 3 – 调整字体大小以适应宽度,多行