[英]javascript: how to access window.top from window.opener?
[英]Access javascripts functions from source WKWebView (window.opener)
在我的 iOS 应用程序中,我有 2 个WKWebView
控件来模拟 Web 应用程序中 2 个选项卡/窗口的父/子关系,以便我们可以重用所有这些 javascript。 问题是这 2 个WKWebView
之间没有通用的通信通道。
网络架构:
- 第一个/主窗口加载我们的内部 javascript 函数,并在第二个/子窗口中打开链接。
- 第二个/子窗口加载第三方网络内容。
- 第三方内容使用 javascript 表单源窗口(使用 window.opener / window.parent API 桥接器)与我们的系统进行通信。
现在,在本机应用程序中,这就是我正在做的重用现有 javascripts 和模拟网络架构的工作 -
一种。 在第 1 个 WKWebView 中从网页调用 js下方-
window.open("http://localhost/child.html", "myWindow", "width=200,height=100");
湾 WKUIDelegate 拦截此调用 (a) 并打开第二个 WKWebView -
- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
// Here, window.open js calls are handled by loading the request in another/new web view
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
WebViewController *webViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"WebViewController"];
webViewController.loadURLString = navigationAction.request.URL.absoluteString;
// Show controller without interfering the current flow of API call, thus dispatch after a fraction of second
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.navigationController pushViewController:webViewController animated:YES];
});
return nil;
}
C。 在web/计算机浏览器中,web app的子窗口可以使用window.opener
和window.parent
访问源js函数
如何在WKWebView
实现相同的功能? 换句话说,第二个WKWebView
js 函数可以从父/源WKWebView
调用 js 函数?
你绝对不应该从webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:
返回nil
,而是你的WKWebView
一个实例。
不幸的是,我现在无法验证这一点。 但据我所知,诀窍还在于不要忽略来自webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:
委托方法的WKWebViewConfiguration
参数,而是创建第二个WKWebView
实例,将此参数作为initWithFrame:configuration:
参数之一传递。
此外,根据 Apple 文档,如果您返回正确的 Web 视图实例,则看起来您不需要自己加载请求。 WebKit 应该为您处理这个问题。
总体而言,您的代码应类似于:
- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
WKWebView *childWebView = [[WKWebView alloc] initWithFrame:CGFrameZero configuration:configuration];
WebViewController *webViewController = [[WebViewController alloc] initWithWebView: childWebView];
// looks like this is no longer required, but I can't check it now :(
// [childWebView loadRequest:navigationAction.request];
// Show controller without interfering the current flow of API call, thus dispatch after a fraction of second
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.navigationController pushViewController:webViewController animated:YES];
});
return childWebView;
}
完成任务的一种更简单的方法是拥有一个 WKWebView,并使用 HTML 将标题和详细信息分开。 最简单的解决方案是拥有一个带有标题和所有详细信息的 HTML 文档,但如果您需要动态添加详细信息,也可以使用 DOM。 使用这种方法,将 Javascript 重用于标题和细节将是最简单的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.