美文网首页工作需要
ios·WKWebView\UIWebView加载HTMLStr

ios·WKWebView\UIWebView加载HTMLStr

作者: 爱迪生的小跟班 | 来源:发表于2019-07-20 11:22 被阅读0次

    背景:
    项目中开发商品类型数据,数据可变性较大,所以商品详情数据存在文案和图片富文本显示,后台返回了html格式的数据供前端展示。
    如果用webView直接显示的话,需要等html内容完全展示才能获取webView需要展示的高度。但是我们需要做到的是,先展示文字和在有图片的地方展示占位图,等待图片加载完成再显示出图片。
    场景:将WKWebView放在TableView的cell中进行展示,就需要计算内容的展示高度以刷新cell的高度。
    实现思路:拿到后台返回的html字符串 - 加入jquery.js - 将拿到的html嵌入到自己创建的html内容 - loadWebViewWithHtmlString

    文中使用到的懒加载jquery.js以及html下载地址: https://github.com/heqican/WebViewLazyLoadImage.git

    上代码:
    从服务端拿到的html如下:

    <img src="https://img01.luckincoffeecdn.com/group1/M00/00/06/CmicNV0ui1GABf-SAAGQDLX5qe8931.jpg" alt="" /><br />
    <ul class="attributes-list" style="font-family:tahoma, arial, " background-color:#ffffff;"="">
    <li style="text-indent:5px;">
        品牌:&nbsp;鼠绘动漫
    </li>
    <li style="text-indent:5px;">
        型号:&nbsp;碗
    </li>
    <li style="text-indent:5px;">
        适用年龄:&nbsp;14周岁以上
    </li>
    <li style="text-indent:5px;">
        周边产品:&nbsp;碗碟
    </li>
    <li style="text-indent:5px;">
        出售状态:&nbsp;现货
    </li>
    <li style="text-indent:5px;">
        动漫地区:&nbsp;日本
    </li>
    <li style="text-indent:5px;">
        大小:&nbsp;现货 微瑕
    </li>
    <li style="text-indent:5px;">
        ACG作品名:&nbsp;海贼王/onepiece
    </li>
    <li style="text-indent:5px;">
        ACG角色名:&nbsp;路
    </li>
        </ul>
    <img src="https://img01.luckincoffeecdn.com/group1/M00/00/06/CmicNF0ui1GAB_dJAAD_t8ZZpH0581.jpg" alt="" /><img src="https://img01.luckincoffeecdn.com/group1/M00/00/06/CmicNV0ui1GAB1YTAAL7Y3yui30725.jpg" alt="" /><img src="https://img01.luckincoffeecdn.com/group1/M00/00/06/CmicNF0ui1KANKycAAHmOHfWUJU987.jpg" alt="" /><br />
    <img src="https://img01.luckincoffeecdn.com/group1/M00/00/06/CmicNV0ui1KALE3pAAKuN6sXwik137.png" alt="" />
    
    

    如果直接显示上面的html加载图片过程需要等待很长时间,才能加载出页面内容。

    开始懒加载处理:
    1、将上方下载的懒加载包,导入工程中:


    image.png

    2、在加载HTMLString前,先组装html数据,让html具有懒加载功能:

    ///实现html图片懒加载
    - (void)lazyloadHTMLImagesWithHTMLString:(NSString *)htmlString complete:(void(^)(NSString *tempHtml, NSURL *baseURL))complete{
        //替换标签
        NSString *originalStr = [htmlString stringByReplacingOccurrencesOfString:@"src" withString:@"data-original"];
        //获取temp文件的路径
        NSString *tempPath = [[NSBundle mainBundle]pathForResource:@"temp" ofType:@"html"];
        //加载temp内容为字符串
        NSString *tempHtml = [NSString stringWithContentsOfFile:tempPath encoding:NSUTF8StringEncoding error:nil];
        //替换temp内的占位符{{Content_holder}}为需要加载的HTML代码
        tempHtml = [tempHtml stringByReplacingOccurrencesOfString:@"{{Content_holder}}" withString:originalStr];
        //LazyloadImage目录下的js文件在根路径,因此需要在加载HTMLString时指定根路径
        NSString *basePath = [[NSBundle mainBundle] bundlePath];
        NSURL *baseURL = [NSURL fileURLWithPath:basePath];
        
        if (complete) {
            complete(tempHtml,baseURL);
        }
    }
    

    3、组装好新的html之后,开始加载html内容:

    ///图片懒加载处理
            [self lazyloadHTMLImagesWithHTMLString:model.htmlDesc complete:^(NSString *tempHtml, NSURL *baseURL) {
                //加载html
                [self.webView loadHTMLString:tempHtml baseURL:baseURL];
                //添加观察者
                [self.webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
            }];
    

    4、给webview添加观察者,监听图片加载情况。等待图片加载完成,重新计算@"document.body.offsetHeight"高度,刷新展示控件的高度

    #pragma mark - 观察者监听
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
        if([keyPath isEqualToString:@"contentSize"]) {//由于图片在实时加载,监听到内容高度变化,需要实时刷新您的控件展示高度 等
            //设置展示元素样式
            [self setWebViewFontStyle];
            //刷新控件高度
            [self refreshWebViewHeight:self.webView];
        }
    }
    
    #pragma mark - webview加载 delegate
    - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
        self.isLoaded = YES;
        [self refreshWebViewHeight:webView];
    }
    
    //计算webView渲染高度并刷新视图
    - (void)refreshWebViewHeight:(WKWebView *)webView{
        [webView evaluateJavaScript:@"document.body.offsetHeight" completionHandler:^(id _Nullable result,NSError * _Nullable error){
            CGFloat height = [result floatValue] + 20;//这里+20
            [self.webView mas_remakeConstraints:^(MASConstraintMaker *make) {
                make.top.mas_equalTo(self.titleLabel.mas_bottom).offset(5);
                make.left.mas_equalTo(self.mas_left).offset(Interval_Size_8);
                make.right.mas_equalTo(self.mas_right).offset(-Interval_Size_8);
                make.height.mas_equalTo(@(height));
            }];
            
            if (self.contentHeight != height+1) {
                self.contentHeight = height+1;
                if (self.contentHeight > 0) {
                    if (self.loadedBlock) {
                        //这里获取到高度之后,根据具体逻辑进行处理
                        self.loadedBlock(self.contentHeight);//高度确定了,回调刷新详情页高度和tableView
                    }
                }
            }
        }];
    }
    
    

    这样就可以实现加载HTMLString 先展示文字和占位符,图片等待加载完成再展示了。

    懒加载效果:
    未加入懒加载之前,等待webview加载需要耗时太久了,体验效果极差。
    加入懒加载后就能完美加载富文本的html啦,管它图片有多大,管它网速有多慢~~
    效果:

    图片加载中.PNG 图片加载完成.PNG

    其他:
    可以往html中注入JS,修改展示样式等等:

    //设置webView 样式
    - (void)setWebViewFontStyle{
        //字体颜色
        [self.webView evaluateJavaScript:@"document.getElementsByTagName('body')[0].style.webkitTextFillColor= '#666666'" completionHandler:nil];
        //修改字体大小
        [self.webView evaluateJavaScript:@"document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '90%'"completionHandler:nil];
        //禁止用户选择
        [self.webView evaluateJavaScript:@"document.documentElement.style.webkitUserSelect='none';" completionHandler:nil];
        [self.webView evaluateJavaScript:@"document.activeElement.blur();" completionHandler:nil];
        // 改变网页内容背景颜色
    //    [self.webView evaluateJavaScript:@"document.body.style.backgroundColor=\"#616465\"" completionHandler:nil];
    }
    
    //处理WKWebView 图片展示超出边界问题
    - (void)processingBeyondTheBorder{
        NSString *js = @"function imgAutoFit() { \
        var imgs = document.getElementsByTagName('img'); \
        for (var i = 0; i < imgs.length; ++i) {\
        var img = imgs[i];   \
        img.style.maxWidth = %f;   \
        } \
        }";
        js = [NSString stringWithFormat:js, [UIScreen mainScreen].bounds.size.width-Interval_Size_8*2];
        //注入JS
        [self.webView evaluateJavaScript:js completionHandler:nil];
        [self.webView evaluateJavaScript:@"imgAutoFit()" completionHandler:nil];
    }
    
    //禁止缩放
    - (void)setWebViewUserUnScalable{
        NSString *js = @"var script = document.createElement('meta');"
        "script.name = 'viewport';"
        "script.content=\"width=device-width, initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0, user-scalable=no\";"
        "document.getElementsByTagName('head')[0].appendChild(script);";
        //注入JS
        [self.webView evaluateJavaScript:js completionHandler:nil];
    }
    
    

    相关文章

      网友评论

        本文标题:ios·WKWebView\UIWebView加载HTMLStr

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