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