zoukankan      html  css  js  c++  java
  • iOS 获取webview高度小结

    不论是UIWebView还是WKWebView对大家来说都是相当熟悉,我们一般用他们来加载网页。

    现在简述下我的进坑心得,如果我们用固定webview高度的方式去展示网页,不论怎样我们都是能够正常展示网页的,但往往有些蛋疼的需求是要我们动态计算webview的高度,换言之就是webview高度根据内容高度自适应。一般我们用以下三种方式去处理

    1、使用JS获取

    @"document.documentElement.offsetHeight"

    @"document.getElementById("content").offsetHeight"

    NSString *tempStr = @"document.body.scrollHeight";

        if (kiOS13System) {

            tempStr = @"document.documentElement.scrollHeight";

        }

    NSString *javscript = [self.webView.URL.host isEqualToString:@"mp.weixin.qq.com"]?@"document.ge("page-content").offsetHeight":tempStr;

    2、使用contentSize获取

       weak_self.webView.scrollView.contentSize.height

    3、使用sizeThatFits方法  

    [weak_self.webView sizeThatFits:CGSizeZero];

    然后问题就来了,如果网页结构是一样的也还可以,但往往我们使用的链接都是五花八门的,微信公众号的,自己的,第三方的等等,所以就出现了此起彼伏的问题。

    先说结论:个人感觉第三种方案更好些,不必关心各种连接问题,能够处理大部分问题,但是某些链接也会有问题。所以终极方案应该是固定高度。

    页面加载完成代理方法

    // 页面加载完成之后调用
    - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
    {
        __weak typeof(self)weak_self = self;
        [self.webView evaluateJavaScript:@"document.documentElement.offsetHeight" completionHandler:^(id _Nullable result,NSError * _Nullable error) {
            if (_optionType == 0) {
                //获取页面高度,并重置webview的frame
                weak_self.webView.height = [result doubleValue];
    //             weak_self.tableView.tableHeaderView = weak_self.webView;
                [weak_self.tableView reloadData];
            }
        }];
    
        __block CGFloat webViewHeight;
        self.webView.height = webView.frame.size.height;
        //获取内容实际高度(像素)@"document.getElementById("content").offsetHeight;"
        NSString *tempStr = @"document.body.scrollHeight";
        if (kiOS13System) {
            tempStr = @"document.documentElement.scrollHeight";
        }
        [webView evaluateJavaScript:tempStr completionHandler:^(id _Nullable result,NSError * _Nullable error) {
            // 此处js字符串采用scrollHeight而不是offsetHeight是因为后者并获取不到高度,看参考资料说是对于加载html字符串的情况下使用后者可以,但如果是和我一样直接加载原站内容使用前者更合适
            //获取页面高度,并重置webview的frame
            webViewHeight = [result doubleValue];
            NSLog(@"%f",webViewHeight);
            dispatch_async(dispatch_get_main_queue(), ^{
                if (webViewHeight != weak_self.webView.height) {
                    webView.frame = CGRectMake(0, 0, self.view.frame.size.width, webViewHeight);
                    [self.tableView reloadData];
    
                }
            });
        }];
        
        NSLog(@"结束加载");
    }

    监听webview的scrollView的contentSize属性

    - (void)addObservers{
        [self.webView addObserver:self forKeyPath:@"scrollView.contentSize" options:NSKeyValueObservingOptionNew context:nil];
    }
    
    - (void)removeObservers{
        [self.webView removeObserver:self forKeyPath:@"scrollView.contentSize"];
    }- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
        if (object == self.webView) {
            if ([keyPath isEqualToString:@"scrollView.contentSize"]) {
                __weak typeof(self)weak_self = self;
    //            NSString *tempStr = @"document.body.scrollHeight";
    //            if (kiOS13System) {
    //                tempStr = @"document.documentElement.scrollHeight";
    //            }
    //
    //
    //            NSString *javscript = [self.webView.URL.host isEqualToString:@"mp.weixin.qq.com"]?@"document.ge("page-content").offsetHeight":tempStr;
    //            [self.webView evaluateJavaScript:tempStr completionHandler:^(id _Nullable result,NSError * _Nullable error) {
    //                //获取页面高度,并重置webview的frame
                    if (_optionType == 1 || _optionType == 2) {
                        if (add_status == 0) {
                            add_status = 1;
    //                        weak_self.webView.height = [result doubleValue];//weak_self.webView.scrollView.contentSize.height;
    //                        weak_self.tableView.tableHeaderView = weak_self.webView;
                        }
                    }else{
                        
                        CGSize size = [weak_self.webView sizeThatFits:CGSizeZero];
                        weak_self.webView.height = size.height;
                        [weak_self.tableView setTableHeaderView:weak_self.webView];
                    }
    
                    DDLogDebug(@"++++%@",@(weak_self.webView.height));
    //            }];
               
            }
    
        }
    }

    最终修改后大部分可以正常显示,未见白屏,但部分公众号文章会有广告图片丢失的问题

    参考文章:

    https://www.jianshu.com/p/6bbcc438b188

    https://www.jianshu.com/p/e98e3747127c

  • 相关阅读:
    React native 之 图标库ECharts的使用
    使用jquery给html标签加点击事件
    React native 之 async/await
    CSS布局之flexbox
    Swiper 的引入
    给浏览器设置一张背景图,并且拉动浏览器大小时图片不要被压缩变形
    境界的彼方_lduoj_bfs宽搜
    2021美国大学生数学建模大赛==ABCDEF+思路解析==
    3045 Lcm与Gcd构造
    对拍程序
  • 原文地址:https://www.cnblogs.com/lijianyi/p/11950702.html
Copyright © 2011-2022 走看看