【问题标题】:How to detect if an image in a html is fully loaded in WKWebView?如何检测 html 中的图像是否在 WKWebView 中完全加载?
【发布时间】:2018-07-13 19:05:23
【问题描述】:

我正在加载带有 标签的本地 html,例如:

< img class="icon" src="data:image/png;base64,/9j/4AAQSkZJRgABAQEAlgCWAAD/7gAOQWRvYmUAZAAAAAAA/...

但是,如何检测图像是否已完全加载?我用这个来检测。但是,它似乎不起作用。有时图像已加载,有时未加载。

-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    if (webView.isLoading) return;
    ..
    //proceed to load the second html
}

更新:

我在 didFinishNavigation 委托中添加了延迟,图像加载完美:

-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
if (webView.isLoading) return;


double delayInSeconds = 3.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    NSLog(@"Do some work");

});

}

但是,这是一个临时解决方案。有没有更好的解决方案?

【问题讨论】:

  • 你可以参考这个帖子:stackoverflow.com/questions/36313253/…
  • 是的,我已经在使用 webView:didFinishNavigation: 来检测。但是,它是在base64图像加载之后触发还是之前触发?

标签: ios objective-c


【解决方案1】:

我的解决方案是使用 javascript 代码检查 webView 的内容高度。如果高度大于或等于数字(表示 webView 中有东西,就是图像),发消息到webView 并使用WKScriptMessageHandler 处理原生代码中的消息。

示例

创建 JavaScript 代码。检查内容的高度是否大于 50,发布消息以检查图像是否已加载。

NSString* source =
    [NSString stringWithFormat:
                  @"var sizeInterval = setInterval("
                   "function() {"
                   "var h = 0;"
                   "var children = document.body.children;"
                   "for (var c = 0; c < children.length; c++) {"
                   "h += children[c].offsetHeight;"
                   "}"
                   "if (h > 50) {"
                   "clearInterval(sizeInterval);"
                   "window.webkit.messageHandlers.%@.postMessage('loaded');"
                   "}"
                   "},"
                   "100);",
                  kContentLoadedMessage];

WKUserScript* script = [[WKUserScript alloc]
      initWithSource:source
       injectionTime:WKUserScriptInjectionTimeAtDocumentStart
    forMainFrameOnly:YES];

WKUserContentController* contentController =
    [[WKUserContentController alloc] init];
[contentController addUserScript:script];
[contentController addScriptMessageHandler:self name:kContentLoadedMessage];

WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = contentController;

YOUR_WK_WEB_VIEW =
    [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
// Add webView to a view and load html

使用WKScriptMessageHandler处理消息。

- (void)userContentController:(WKUserContentController*)userContentController
      didReceiveScriptMessage:(WKScriptMessage*)message {
  if ([message.name isEqualToString:kContentLoadedMessage]) {
    NSLog(@"Image was loaded");
  }
}

您可以查看my demo repo了解更多。

【讨论】:

  • 嗨@trungduc,如果没有加载图像帧,这是一个很好的技巧。在我的情况下,图像框架在那里(因此,当图像加载和不加载时,webview的高度是相同的)只是图像没有加载:(
  • 好的,我知道了。你能告诉我你改变图像的方式吗?我认为我们只需要更改 javascript 以适应您的问题。
  • 我只是使用一个简单的图像标签,数据源是base64格式,如问题所示。
  • 所以如果图片没有加载,src 将为空。对吗?
  • 这个问题很难复制。您是否能够使用非常大的数据源对其进行测试?理论上,当图像未加载时,源将为空。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 2020-05-18
相关资源
最近更新 更多