如何准确判断 WebView 加载完成
如何准确判断 WebView 加载完成
原文地址:http://www.jianshu.com/p/897e2d82ee43
正常情况下我们把处理网页加载完毕的代码放在- (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种。
1、uninitialized : 还没开始加载
2、loading : 加载中
3、loaded : 加载完成
4、interactive : 结束渲染,用户已经可以与网页进行交互。但内嵌资源还在加载中
5、 complete : 完全加载完成
WebViewDidFinishLoad 被调用时,readyState 可能处在 interactive 和 complete 两种状态。当我们需要对网页中的元素进行修改时,最好在 complete 状态进行,不然我们的修改可能被重置。例如百度登录页(http://wappass.baidu.com/passport) 在iPad上打开时,WebViewDidFinishLoad 的 readyState 就是 interactive,这时如果修改输入框里内容(账号密码自动填充),我们的修改将会在 complete 状态时被重置。
为了解决这个问题,我们可以在 WebViewDidFinishLoad 判断 readyState 的状态,如果不是 complete,则重写 window.onload 或者 document.onreadystatechange 两个方法,他们都可以准确判断内嵌资源加载完毕的时机。然后通过 JSExport 回调 Objective-C 代码(如果是 WKWebView 则通过 MessageHandler 回调)。
对 JSExport 还不熟悉可以参考 这篇博客 来简单了解 JSExport 的使用。
- (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];
}
在普通网页加载时打印结果是:
1、documentReadyStateComplete
2、 onload
3、webViewDidFinishLoad:
而本例中打印结果则是:
1、webViewDidFinishLoad:
2、documentReadyStateComplete
3、onload
不管 webViewDidFinishLoad 在何时调用,webViewDidFinishLoadCompletely 都保证在加载完成的时候触发。
。
本文的完整代码可以在 XFNewsContentDemo 中查看。本问与上篇博客共用 Demo,所以 Demo 中有大量与本篇不相关的代码。你只需要找到上述引用代码的部分查看即可。
参考资料
[MDN] document.readyState
[w3schools] HTML DOM readyState Property
[CNBlogs]iOS判断UIWebView加载完成的方法
如何准确判断 WebView 加载完成相关推荐
- android 判断webview加载成功,Android:如何检查使用webview.loadUrl时url的成功加载
不幸的是,目前在WebView中没有简单的方法来确保页面上的所有内容都已成功加载.我们希望在未来的版本中提供更好的API.让我解释一下你现在可以做什么. 首先,为了检测阻止WebView连接服务器加载 ...
- 【MFC】在CHtmlView中准确判断页面加载完成
以前的方法繁琐,这里抄了别人的方法,做了简单修改.记录下. 首先要在CHtmlView的子类中,重载如下函数: virtual void DocumentComplete(LPDISPATCH pDi ...
- android判断webview加载完成,android webView判断是否加载完成的2种办法
=================================== mWebView.setWebViewClient(new WebViewClient() { @Override public ...
- Android—WebView加载速度优化工程实践
一.混合开发的优势与缺陷 在混合开发大行其道的今天,很多页面和功能都转由前端实现,客户端只要在APP中嵌入一个WebView即可,同时前端开发的页面对于Android和iOS端的效果是统一的,省去了适 ...
- Android使用WebView加载网页
在AndroidManifest.xml设置访问网络权限: <span style="font-size:24px;"><span style="fon ...
- 利用web实现android的界面,利用WebView加载手机端网页实现APP封装
**思路 : ** 安卓端只使用一个Activity 此Activity中只包含WebView这个控件 并且隐藏此Activity的标题栏 这样只要我们前端对手机浏览器的适配做的很好 我们这个WebV ...
- Android WebView加载完成的监听
在项目里有时会需要监听WebView加载完成的状态,可能有人会使用WebViewClient里onPageFinished这个方法来监听,可是这个官方的方法到现在还是不稳定,有些能监听到,有些则不能. ...
- webview加载的页面和浏览器渲染的页面不一致_QQ音乐Android客户端Web页面通用性能优化实践...
QQ音乐 Android 客户端的 Web 页面日均 PV 达到千万量级,然而页面的打开耗时与 Native 页面相距甚远,需要系统性优化.本文将介绍 QQ 音乐 Android 客户端在进行 Web ...
- webview 加载php页面内容,WebView加载优化的方法介绍
本篇文章给大家带来的内容是关于WebView加载优化的方法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. WebView加载优化 当WebView的使用频率变得频繁的时候,对于其 ...
- webview加载本地资源的各种尝试
1.webview 打开sd卡上的静态html文件 ,js文件既然放在assets文件夹下能找到,那能通过放在sd卡,能加载吗? 答:事实证明,是没有用的. 2.既然能拿到html的数据,那我们是不是 ...
最新文章
- smc数显压力表设定方法_压力控制器工作原理与设定方法
- C#访问Access和Win7 64位下可能遇到的 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0” 提供程序 问题
- python format 字典_python 用字典格式化字符串
- lucene.NET详细使用与优化详解
- 你买过假芯片吗?元器件专家为您揭秘假冒芯片的套路!
- JS-对象-构造函数-实例化-this
- greenplum mysql jdbc_Kylin设置JDBC配置greenplum数据源
- 登录oracle sql,登录 Oracle SQL Developer
- echarts 大屏模板_年会策划万能模板 ,玩转年会看这篇!
- java websocket
- ContentObserve的基本使用方法
- 小班计算机游戏教案,小班游戏简单教案(通用11篇)
- pygame 绘制爱心函数 r = 1-cos(θ). Tag: python | 图形界面 | GUI
- 毕业设计 高校排课系统
- 2018 工作日节假日字典表
- Linux桌面环境(桌面系统)大比拼[附带优缺点]
- “程序猿”面试篇(一)聊项目
- 量化 计算机 金融,金融数据量化分析(上)
- C++之getch(),getche(),getchar()的区别
- Mn掺杂CdS量子点|锰掺杂硫化镉量子点|MnS/ZnS/CdS量子点的制备方法图示
热门文章
- VUE 下载文件错误 Proxy error: Could not proxy request xxx from xxx to xxx. HPE_INVALID_HEADER_TOKEN
- [独有源码]springboot医养结合养老APP的设计与实现a7rv0借鉴他人经验,找到适合自己的毕业设计
- [Go练习]跳水比赛8个评委打分问题(存在多个最差评委版)
- Python 学习日记day 7
- nested exception is org.apache.ibatis.binding.BindingException: Parameter 'xxxx' not found. Avai解决办法
- PHP-10-mysql
- 二维burgers方程_二维Burgers方程的格子Boltzmann模型
- idea2020 java - 不能执行jar文件: “no main manifest attribute”的解决办法
- npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! webpack_test@1.0.0 dev: `webpack` npm ERR! Exit s
- custoj zzj穿裙子 C++