WKWebView 在触发原生代码之前等待 DOM 渲染

Posted

技术标签:

【中文标题】WKWebView 在触发原生代码之前等待 DOM 渲染【英文标题】:WKWebView wait for DOM rendering before triggering native code 【发布时间】:2015-05-01 10:45:37 【问题描述】:

我有一个包含WKWebView 的混合ios 应用程序,并且我有一个javascript 函数callNative 可以在主线程中调用Objective C 本机代码。

在我的 JavaScript 中,我有以下结构

modifyDOM(); // e.g. .show(), and .hide() stuff
callNative('animateWKWebViewFrame');

由于某种原因,animateWKWebViewFrame(本机代码)被调用之前 modifyDOM 完成并完全呈现。 (这会导致视觉故障。)

如何在调用本机代码之前强制完整呈现 DOM 修改?

【问题讨论】:

你能告诉我们modifyDOM()方法的一部分吗?您提到它不包含任何动画-也许您弄错了...您是否尝试在modifyDOM()callNative 之间添加日志或警报语句,并且可能在modifyDOM() 的实际实现结束时添加!? 【参考方案1】:

我假设您正在使用 jQuery,因为您的评论说 modifyDOM 调用 show()hide()。如果是这种情况,那么您应该依靠 complete 参数来提供一个函数,该函数将依次调用您的本机代码。

相关文档在这里:http://api.jquery.com/hide/#hide-duration-completehttp://api.jquery.com/show/#show-duration-complete

最后,这里是一些示例代码:

function modifyDOM()

  someElement.show(400, function() callNative('animateWKWebViewFrame'););

【讨论】:

动画是即时的。他们应该立即完成。 那么你可以在我提供的代码示例中将 400 的持续时间替换为 0 并试一试。如果它不能解决您的故障,那么也许您可以提供有关发生故障的更多详细信息以及您为 WebView 框架设置动画的测量方式。 考虑到您没有提供任何新信息来解决您的问题,这里又是一个盲注。我猜您的更改会影响您的内容的大小,并且您提取的用于动画 WebView 框架的测量值是错误的,因为渲染尚未结束。如果是这种情况,请确保您使用此处记录的 getComputedStyle 函数检索内容的大小:developer.mozilla.org/en-US/docs/Web/API/Window/…【参考方案2】:

要不要再做一个回调来检测 modifyDOM() 函数?

// alloc webview
    WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init];
    [theConfiguration.userContentController addScriptMessageHandler:self name:@"interOp"];
    self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 0, 0) configuration:theConfiguration];

一旦你的 modifyDOM() 函数完成,你调用“interOp”回调,然后你可以用任何想要的回调initial() 并调用 animateWKWebViewFrame

- (void)userContentController:(WKUserContentController *)userContentController
      didReceiveScriptMessage:(WKScriptMessage *)message 

    NSDictionary *sentData = (NSDictionary*)message.body;
    NSString* command = sentData[@"command"];

    LOG(@"[userContentController] command(%@)", command);

    if ( [command isEqualToString:@"DOMReady"] ) 
        // defining a JavaScript function
        NSString *jsFunctionText = @"Initiate("
                                    "command:animateWKWebViewFrame"
                                    ");";
        [self.webView evaluateJavaScript:jsFunctionText completionHandler:^(id object, NSError * err) 
            if ( err ) 
                LOG(@"[evaluateJavaScript] error(%@)", err);
            
        ];
     

【讨论】:

我不是 100% 确定你的方法有效。当您编写“一旦您的 modifyDOM() 函数完成...”时,问题是 JavaScript 领域可能认为 modifyDOM() 已完成执行,而实际上在渲染领域中的东西仍在管道中。

以上是关于WKWebView 在触发原生代码之前等待 DOM 渲染的主要内容,如果未能解决你的问题,请参考以下文章

vue怎么触发元素的原生事件

iOS WKWebView JS 与 原生交互小结

JavaScript 同步原生通信到 WKWebView

iOS原生与H5交互WKWebView

iOS 野路子获取WKWebView内容高度做H5原生连接

2、react使用原生js模拟长按操作