繁体   English   中英

从源 WKWebView (window.opener) 访问 javascripts 函数

[英]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.openerwindow.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM