本文章只针对iOS初级开发者,如果大家有更好的意见欢迎在下方留言。
不知道大家有没有遇到这样的问题,就是后台返回的数据里面有一段html格式的数据里面包含文字和众多的图片,然后在客户端通过webView加载这段数据,但是当图片太多的时候轻则会特别慢重则会导致占用太多内存导致手机内存不足退出app,显然不能满足公司产品的要求。
为了解决这个问题真是搓破了脑瓜最后还是没有解决,无意中看到了一个帖子关于懒加载html数据中的图片,但是众说纷纭好多关于这种问题的描述,没有个能参考的帖子,所以今天在这里坐下来写这个帖子希望能帮助和我一样遇到此类问题的程序员。
关于解决这个问题需要准备一下一些东西:
1. jquery-3.1.1.js -- 官网下载地址( jquery库官方下载 )
2. jquery.lazyload.js -- 官网下载地址( jquery.lazyload官方下载 )
3. 基本掌握js语法(当然不会也没关系)
废话不多说了,接下来上代码
//添加到约束的html字符串(为了简单约束已去掉),content为返回的html格式字符串
NSString*str = [NSStringstringWithFormat:@"%@"content];
//将html字符串中的src替换为data-original否则jquery不会实现懒加载******
NSString*htmlReplaceString = [strstringByReplacingOccurrencesOfString:@"src"withString:@"data-original"];
//获取temp文件的路径(temp文件为实现懒加载的js核心代码)
NSString*tempPath = [[NSBundlemainBundle]pathForResource:@"temp"ofType:@"html"];
//加载temp内容为字符串
NSString*tempHtml = [NSStringstringWithContentsOfFile:tempPathencoding:NSUTF8StringEncodingerror:nil];
//替换temp内的占位符{{Content_holder}}为需要加载的HTML代码
tempHtml = [tempHtmlstringByReplacingOccurrencesOfString:@"{{Content_holder}}"withString:htmlReplaceString];
//Temp目录下的js文件(temp文件和jquery库)在根路径,因此需要在加载HTMLString时指定根路径
NSString*basePath = [[NSBundlemainBundle]bundlePath];
NSURL*baseURL = [NSURLfileURLWithPath:basePath];
//加载HTMLString
[_webViewloadHTMLString:tempHtmlbaseURL:baseURL];
以上代码加上本地的temp文件就可以实现一个html数据的懒加载,但是有时候我们不单单是在一个界面只加载一个webview,比如说在tableview的头视图上加载一个webview,但是webview懒加载时通过
[webViewstringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight;"]
计算出来的高度是不包含懒加载的图片的高度的,如果图片有占位图那么这里计算出来的高度只是文字的高度与占位图的高度的和,因此就需要在图片动态加载的过程中动态的来计算webview的高度。
在这里通过给webview里面的scrollview的contentSize设置一个监听
[_webView.scrollViewaddObserver:selfforKeyPath:@"contentSize"options:NSKeyValueObservingOptionNewcontext:nil];
当图片动态的加载出来以后contentSize就会改变因此就会被监听到来重新给webview设置高度。
- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
{
if([keyPathisEqualToString:@"contentSize"]) {
//检测contentSize的实时的高度
webViewHeight=_webView.scrollView.contentSize.height;
if(_webView.height==webViewHeight) {//实时高度和上次webView的高度作比较,如果相等了说明图片全部加载完成,否则没有则需要重新给webview高度赋值并且刷新tableview
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
//重新将webview的高度设置为scrollview的内容高度
_webView.frame=CGRectMake(10,60,MainScreenWidth-10,webViewHeight+30);
//重新给headerView的frame赋值
_upView.frame=CGRectMake(0,0,UI_SCREEN_WIDTH,60+webViewHeight+90+70);
_tableView.tableHeaderView=_upView;
[_tableViewreloadData];
});
}
}
这里遇到一个小坑:当占位图的高度比实际图片的高度高的时候webview的高度还是文字和占位图的高度的和,就会在底部留出一个空白区域,目前还没有好的方法解决只能用高度比较小的占位图😋 如果大家有好的解决办法欢迎积极分享。
demo下载地址 demo传送门