美文网首页
UIWebView监听网页加载完成

UIWebView监听网页加载完成

作者: _RG | 来源:发表于2019-11-19 19:17 被阅读0次

最近接到一个需求,需要获取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

相关文章

网友评论

      本文标题:UIWebView监听网页加载完成

      本文链接:https://www.haomeiwen.com/subject/jjxgictx.html