最近接到一个需求,需要获取WebView加载完成后的的真实高度,
想到的解决方案是在webViewDidFinishLoad
里面获取self.webView.scrollView.contentSize.heigh
高度
在实现过程中发现webViewDidFinishLoad
调用时, 网页里面的内容并非完全加载完毕, 比如网页里面有重定向或者视频时,webViewDidFinishLoad
调用但webView里面的内容并没有全部加载完成 。此时通过self.webView.scrollView.contentSize.heigh
获取的高度并不是网页内容的最终高度,
通过研究发现可以通过监听JS里面的document.onreadystatechange
方法来确认网页加载完成, 当document.readyState
改变时,JS里面的document.onreadystatechange
会被调用,
因此可以在webViewDidFinishLoad时进行判断
@interface TestWebViewController () <UIWebViewDelegate>
@property(nonatomic,strong) UIWebView *webView;
/************************JavaScriptCore*************************/
@property(nonatomic,strong) JSContext *jscontext;
@property(nonatomic,strong) TestJsExport *jsExport;
@end
@implementation TestWebViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.jsExport = [TestJsExport new];
self.jsExport.webViewLoadStateComplete = ^{
//完全加载完成后调用
};
//自己实现webview的创建和加载
[self addSubview];
[self loadHtml];
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
self.jscontext = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
self.jscontext[@"OCContext"] = _jsExport;
NSLog(@"_jsExport = %@",_jsExport);
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if (!webView.isLoading) {
NSString *readyState = [webView stringByEvaluatingJavaScriptFromString:@"document.readyState"];
NSLog(@"readyState = %@",readyState);
if ([readyState isEqualToString:@"complete"]) {
/**
document.readyState为complete时,证明已经完全加载完成
此时获取通过self.webView.scrollView.contentSize.height获取内容高度进行重新布局
*/
self.jsExport.webViewLoadStateComplete();
}else {
/**
此时网页并没有完全加载完成所有的资源
可以用过以下代码植入JS函数,在OC代码里面进行监听
*/
/*
注意 OCContext.documentReadyStateComplete 里面的方法
就是对于自己实现的JSExport协议里面的方法documentReadyStateComplete
*/
NSString *jsString =
@"window.onload = function() {"
@" OCContext.onload();"
@"};"
@"document.onreadystatechange = function () {"
@" if (document.readyState == \"complete\") {"
@" OCContext.documentReadyStateComplete();"
@" }"
@"};";
[_webView stringByEvaluatingJavaScriptFromString:jsString];
}
}
}
@end
JSExport是iOS和JS交互的一种方式
通过继承JSExport
协议进行交互
下面是JSExport类相关实现代码
#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>
NS_ASSUME_NONNULL_BEGIN
///JSExport 可以用来监听webView里面的方法调用,
//创建一个继承JSExport的协议,并实现一个继承JSExport协议的类
@protocol TestJsExportProtocal <JSExport>
- (void)onload;
- (void)documentReadyStateComplete;
@end
@interface TestJsExport : NSObject <TestJsExportProtocal>
///完全加载完成的操作
@property(nonatomic,copy) void(^webViewLoadStateComplete)(void);
@end
NS_ASSUME_NONNULL_END
#import "TestJsExport.h"
@implementation TestJsExport
- (void)onload {
}
- (void)documentReadyStateComplete {
if (self.webViewLoadStateComplete) {
self.webViewLoadStateComplete();
}
}
@end
网友评论