close
当前位置: 物联网在线 > 技术文库 > ios >

如何准确判断 WebView 加载完成

正常情况下我们把处理网页加载完毕的代码放在 - (void)webViewDidFinishLoad:(UIWebView *)webView 里。但 WebViewDidFinishLoad 时网页真的加载完了吗?

官方文档并没有说明 WebViewDidFinishLoad 到底在什么时候被调用,但事实证明在某些情况下 WebViewDidFinishLoad 可能不是你想要的时机。

网页重定向

当网页重定向发生时,网址被重定向几次,WebViewDidFinishLoad 就会被调用几次。所以如果你只想在最后加载完成时调用某些代码,可以通过 webView.isLoading 来判断。当 WebViewDidFinishLoad 时如果 webView.isLoading == YES 那么说明网页可能发生了重定向。

- (void)webViewDidFinishLoad:(UIWebView *)webView { if (!webView.isLoading) { [self webViewDidFinishLoadCompletely]; } } 加载内嵌资源

除了原生方法外,网页的 readyState 属性也可以返回当前加载状态,共有5种。

uninitialized : 还没开始加载

loading : 加载中

loaded : 加载完成

interactive : 结束渲染,用户已经可以与网页进行交互。但内嵌资源还在加载中

complete : 完全加载完成

WebViewDidFinishLoad 被调用时,readyState 可能处在 interactive 和 complete 两种状态。当我们需要对网页中的元素进行修改时,最好在 complete 状态进行,不然我们的修改可能被重置。例如百度登录页在iPad上打开时,WebViewDidFinishLoad 的 readyState 就是 interactive,这时假设想要在输入框里自动填写账号密码并修改输入框背景为黄色,我们的修改将会在 complete 状态时被重置。

为了解决这个问题,我们可以在 WebViewDidFinishLoad 判断 readyState 的状态,如果不是 complete,则重写 window.onload 或者 document.onreadystatechange 两个方法,他们都可以准确判断内嵌资源加载完毕的时机。然后通过 JSExport 回调 Objective-C 代码(如果是 WKWebView 则通过 MessageHandler 回调)

- (void)webViewDidStartLoad:(UIWebView *)webView { _jsContext = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; _jsContext[@"xfNewsContext"] = _jsExport; } - (void)webViewDidFinishLoad:(UIWebView *)webView { if (!webView.isLoading) { NSString *readyState = [webView stringByEvaluatingJavaScriptFromString:@"document.readyState"]; BOOL complete = [readyState isEqualToString:@"complete"]; if (complete) { [self webViewDidFinishLoadCompletely]; } else { NSString *jsString = @"window.onload = function() {" @" xfNewsContext.onload();" @"};" @"document.onreadystatechange = function () {" @" if (document.readyState == \"complete\") {" @" xfNewsContext.documentReadyStateComplete();" @" }" @"};"; [_webView stringByEvaluatingJavaScriptFromString:jsString]; } NSLog(@"%@", NSStringFromSelector(_cmd)); } } - (void)onload { [self webViewDidFinishLoadCompletely]; NSLog(@"%@", NSStringFromSelector(_cmd)); } - (void)documentReadyStateComplete { [self webViewDidFinishLoadCompletely]; NSLog(@"%@", NSStringFromSelector(_cmd)); } - (void)webViewDidFinishLoadCompletely { [self displayContent]; }

在普通网页加载时打印结果是:

documentReadyStateComplete

onload

webViewDidFinishLoad:

而本例中打印结果则是:

webViewDidFinishLoad:

documentReadyStateComplete

onload

不管 webViewDidFinishLoad 在何时调用,webViewDidFinishLoadCompletely 都保证在加载完成的时候触发。

参考资料

[MDN] document.readyState

[w3schools] HTML DOM readyState Property

[CNBlogs]iOS判断UIWebView加载完成的方法


(责任编辑:ioter)

用户喜欢...

飞行时间传感器(ToF)如何工作?看看ToF 3D相机

飞行时间传感器如何确定距离?使用示例3D相机了解有关ToF相机的更多信息。 有三种领先的3D成像技术可以在手机和汽车中竞争空间。这些技术是立体成像,结构光投影和飞行时间(或ToF)相机...


如何快速连接到云端并向其直接发送物联网数据然后进行远程访问

许多开发人员都在开发需要连接到云端的物联网 (IoT) 项目,以便进行数据存储和远程访问,以及使用即时的数据分析服务。然而,开发人员很难找到最有效、安全的连接方法。 本文将介绍如何...


什么是物联网?物联网如何运作

最简单的物联网是一个智能设备网络 - 从你从牛奶到工业传感器时提醒你的冰箱 - 连接到互联网以便他们可以共享数据,但物联网远非IT部门面临的一个简单挑战。 什么是物联网? 对于许多公...


如何利用物联网保护我们的家园和城市免受气候变化的影响

过去十年中,自然灾害显着增加。极端天气事件,野火,地震,海啸以及干旱和极地涡旋等缓慢发生的灾害使许多美国家庭处于危险之中。阿拉巴马州最近的龙卷风爆发和2018年在加利福尼亚创...


思考物联网(IoT)如何对音乐产业产生影响!

许多人会认为音乐是他们日常生活中非常重要的一部分。它围绕着我们的生活,工作和娱乐,让我们思考物联网(IoT)如何对音乐产业产生影响! 在本文中,我们将在现场音乐会设置中探索物...


带你看看毫米波雷达芯片发展趋势如何?

随着自动驾驶技术的发展,相关的毫米波雷达也得到了许多关注。毫米波雷达在自动驾驶领域,是与激光雷达LiDAR和摄像头一样极其重要的传感器。同时,我们将会看到,毫米波雷达除了在无人...


如何用旋转变压器精确确定电机角位和速度

电子监控和控制机械系统,如工业电机,伺服系统,机器人和车辆动力传动系,对提高效率,可靠性和安全性非常重要。然而,有效控制需要高精度的角度和速度旋转确定,这由于电噪声和恶劣...


NB-IoT凉凉?5G如何?

在过去这几年,NB是当之无愧的行业网红,备受追捧。三大运营商拼命推动它的商用落地,政府也出台了各项文件政策给它铺路。设备商们更不用说了,不遗余力地对它进行宣传造势。 可是,短...


为什么以及如何使用串行外设接口来简化多个设备之间的连接

嵌入式系统可使用一个或多个处理器或微控制器,在更复杂的系统中执行专用操作。这些嵌入式控制器需要与其他系统元件、传感器甚至其他控制器进行通信。虽然复杂的串行接口和协议很常见...


银行业的未来将如何依赖物联网

今天的世界越来越紧密,这主要归功于互联网和现在 的物联网(IoT) 。物联网改变了人们追踪健身水平,保护家园等的方式。 不出所料,它也引起了各个 行业的全行业转变 。银行业就是其中...