開發(fā)中贫导,有時候我們需要展現(xiàn)HTML類型的數(shù)據(jù)件相,這時候声诸,我們多數(shù)選擇用UIWebView加載殊橙,但是當我們需要加載大量的HTML數(shù)據(jù)時衬衬,使用UIWebView加載殖妇,性能會降低刁笙,尤其是當UITableViewCell需要放大量的HTML數(shù)據(jù)時,如果你用UIWebView加載這些HTML數(shù)據(jù)谦趣,你會發(fā)現(xiàn)疲吸,tableview會有卡頓的現(xiàn)象。
那怎樣去優(yōu)化這個卡頓現(xiàn)象呢前鹅?我們知道WKWbebView的加載速度比UIWebView提升差不多一倍的, 內存使用上面,反而還少了一半摘悴,所以我們可以采用WKWebView對其進行優(yōu)化。今天把一個三方類介紹給大家舰绘,那就是IMYWebView,這個類兼容WKWebView和UIWebView蹂喻,實現(xiàn)了UIWebView到WKWebView的對接,即使你之前的項目是用的UIWebView,那也沒關系捂寿,只要將UIWebView換成IMYWebView就可以了口四。
另外,加載HTML數(shù)據(jù)自然絕多數(shù)會有圖片和內置鏈接秦陋,我們也會希望可以點擊圖片進行瀏覽蔓彩、放大和縮小,可以點開鏈接驳概,那么赤嚼,該怎樣去實現(xiàn)呢?
1顺又、在工程中導入IMYWebView
#import "IMYWebView.h"
2更卒、創(chuàng)建IMYWebView,并嵌套到TableView中,實現(xiàn)tableview的相關代理方法
@interface ViewController ()<UITableViewDataSource, UITableViewDelegate,IMYWebViewDelegate,HZPhotoBrowserDelegate>
@property(nonatomic, strong)UITableView *tableView;
@property(nonatomic, assign)CGFloat webviewHight;//記錄webview的高度
@property(nonatomic, copy)NSString *HTMLData;//需要加載的HTML數(shù)據(jù)
@property(nonatomic, strong)NSMutableArray *imageArray;//HTML中的圖片個數(shù)
@property(nonatomic, strong)IMYWebView *IMYwebView;
@end
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.navigationBar.translucent = NO;
self.title = @"tableviewcell嵌套webview載HTML";
self.view.backgroundColor = [UIColor whiteColor];
// 獲取HTML數(shù)據(jù)
[self getHTMLData];
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width , self.view.frame.size.height - 64) style:UITableViewStylePlain];
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.tableHeaderView = [[UIView alloc] init];
[self.view addSubview:_tableView];
_htmlWebView = [[IMYWebView alloc] init];
_htmlWebView.frame = CGRectMake(0, 0, _tableView.frame.size.width, 1);
_htmlWebView.delegate = self;
_htmlWebView.scrollView.scrollEnabled = NO;//設置webview不可滾動待榔,讓tableview本身滾動即可
_htmlWebView.scrollView.bounces = NO;
_htmlWebView.opaque = NO;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 4;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row != 3) {
return 60;
}else{
return _webviewHight;//cell自適應webview的高度
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
if (indexPath.row == 3) {
[cell.contentView addSubview:_htmlWebView];
//加載HTML數(shù)據(jù)
[_htmlWebView loadHTMLString:_HTMLData baseURL:nil];
}else{
cell.textLabel.text = [NSString stringWithFormat:@"第%ld行",(long)indexPath.row];
}
return cell;
}
3逞壁、實現(xiàn)IMYWebView的相關代理方法
-(void)webViewDidFinishLoad:(IMYWebView *)webView{
//加載完畢后重新計算webview的高度
[self.htmlWebView evaluateJavaScript:@"document.documentElement.scrollHeight" completionHandler:^(id object, NSError *error) {
CGFloat height = [object integerValue];
if (error != nil) {
}else{
_webviewHight = height;
[_tableView beginUpdates];
self.htmlWebView.frame = CGRectMake(_htmlWebView.frame.origin.x,_htmlWebView.frame.origin.y, _tableView.frame.size.width, _webviewHight );
[_tableView endUpdates];
}
}];
// 插入js代碼流济,對圖片進行點擊操作
[webView evaluateJavaScript:@"function assignImageClickAction(){var imgs=document.getElementsByTagName('img');var length=imgs.length;for(var i=0; i < length;i++){img=imgs[i];if(\\"ad\\" ==img.getAttribute(\\"flag\\")){var parent = this.parentNode;if(parent.nodeName.toLowerCase() != \\"a\\")return;}img.onclick=function(){window.location.href='image-preview:'+this.src}}}" completionHandler:^(id object, NSError *error) {
}];
[webView evaluateJavaScript:@"assignImageClickAction();" completionHandler:^(id object, NSError *error) {
}];
//獲取HTML中的圖片
[self getImgs];
}
-(BOOL)webView:(IMYWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
if ([request.URL isEqual:@"about:blank"])
{
return true;
}
if ([request.URL.scheme isEqualToString: @"image-preview"])
{
NSString *url = [request.URL.absoluteString substringFromIndex:14];
//啟動圖片瀏覽器, 跳轉到圖片瀏覽頁面
if (_imageArray.count != 0) {
HZPhotoBrowser *browserVc = [[HZPhotoBrowser alloc] init];
browserVc.imageCount = self.imageArray.count; // 圖片總數(shù)
browserVc.currentImageIndex = [_imageArray indexOfObject:url];//當前點擊的圖片
browserVc.delegate = self;
[browserVc show];
}
return NO;
}
// 用戶點擊文章詳情中的鏈接
if ( navigationType == UIWebViewNavigationTypeLinkClicked ) {
WebViewURLViewController *webViewVC = [WebViewURLViewController new];
webViewVC.URLString = request.URL.absoluteString;
[self.navigationController pushViewController:webViewVC animated:YES];
return NO;
}
return YES;
}
4腌闯、獲取文章圖片個數(shù)的方法
#pragma mark -- 獲取文章中的圖片個數(shù)
- (NSArray *)getImgs
{
NSMutableArray *arrImgURL = [[NSMutableArray alloc] init];
for (int i = 0; i < [self nodeCountOfTag:@"img"]; i++) {
NSString *jsString = [NSString stringWithFormat:@"document.getElementsByTagName('img')[%d].src", i];
[_htmlWebView evaluateJavaScript:jsString completionHandler:^(NSString *str, NSError *error) {
if (error ==nil) {
[arrImgURL addObject:str];
}
}];
}
_imageArray = [NSMutableArray arrayWithArray:arrImgURL];
return arrImgURL;
}
// 獲取某個標簽的結點個數(shù)
- (NSInteger)nodeCountOfTag:(NSString *)tag
{
NSString *jsString = [NSString stringWithFormat:@"document.getElementsByTagName('%@').length", tag];
int count = [[_htmlWebView stringByEvaluatingJavaScriptFromString:jsString] intValue];
return count;
}
5绳瘟、點擊圖片進行瀏覽的相關方法,這個圖片瀏覽是封裝好的一個瀏覽器姿骏,在這里暫時不做介紹
#pragma mark - photobrowser代理方法
- (UIImage *)photoBrowser:(HZPhotoBrowser *)browser placeholderImageForIndex:(NSInteger)index
{
//圖片瀏覽時糖声,未加載出圖片的占位圖
return [UIImage imageNamed:@"gg_pic@2x"];
}
- (NSURL *)photoBrowser:(HZPhotoBrowser *)browser highQualityImageURLForIndex:(NSInteger)index
{
NSString *urlStr = [self.imageArray[index] stringByReplacingOccurrencesOfString:@"thumbnail" withString:@"bmiddle"];
6、最后的運行結果如圖:
7.有時候我們需要給webview加個頭視圖或者尾視圖分瘦,跟隨webview一起滾動蘸泻,如果這時我們的webview不是嵌在tableview中的,那該怎么辦呢嘲玫?很簡單悦施,只要將頭視圖加在webview的scrollview上,設置scrollview的contentInset(UIEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right)頭視圖的高度為top去团,尾視圖的高度為bottom,根據(jù)自己的需要去設置相應的高度)就可以了
//給scrollview添加頭視圖
//設置web view的scrollView的上抡诞、左、下土陪、右的距離
_wkwebView.scrollView.contentInset = UIEdgeInsetsMake(40, 0, 0, 0);
_titleLabel = [[UILabel alloc] init];
[_wkwebView.scrollView addSubview:_titleLabel];
_titleLabel.frame = CGRectMake(0, -40, self.wkwebView.frame.size.width, 40);
[self.wkwebView.scrollView addSubview:_titleLabel];
_titleLabel.text = @"web view的頭視圖";
8昼汗、最后,給大家分享一些用js獲取網頁一些相關元素的代碼
document:屬性
document.title //設置文檔標題等價于HTML的<title>標簽
document.bgColor //設置頁面背景色
document.fgColor //設置前景色(文本顏色)
document.linkColor //未點擊過的鏈接顏色
document.alinkColor //激活鏈接(焦點在此鏈接上)的顏色
document.vlinkColor //已點擊過的鏈接顏色
document.URL //設置URL屬性從而在同一窗口打開另一網頁
document.fileCreatedDate //文件建立日期鬼雀,只讀屬性
document.fileModifiedDate //文件修改日期顷窒,只讀屬性
document.fileSize //文件大小,只讀屬性
document.cookie //設置和讀出cookie
document.charset //設置字符集 簡體中文:gb2312
document:方法
document.write() //動態(tài)向頁面寫入內容
document_createElement_x_x(Tag) //創(chuàng)建一個html標簽對象
document.getElementByIdx_x_x(ID) //獲得指定ID值的對象
document.getElementsByName(Name) //獲得指定Name值的對象
document.body.a(oTag)
body:子對象
document.body //指定文檔主體的開始和結束等價于<body></body>
document.body.bgColor //設置或獲取對象后面的背景顏色
document.body.link //未點擊過的鏈接顏色
document.body.alink //激活鏈接(焦點在此鏈接上)的顏色
document.body.vlink //已點擊過的鏈接顏色
document.body.text //文本色
document.body.innerText //設置<body>...</body>之間的文本
document.body.innerHTML //設置<body>...</body>之間的HTML代碼
document.body.topMargin //頁面上邊距
document.body.leftMargin //頁面左邊距
document.body.rightMargin //頁面右邊距
document.body.bottomMargin //頁面下邊距
document.body.background //背景圖片
document.body.a(oTag) //動態(tài)生成一個HTML對象
location:子對象
document.location.hash // #號后的部分
document.location.host // 域名+端口號
document.location.hostname // 域名
document.location.href // 完整URL
document.location.pathname // 目錄部分
document.location.port // 端口號
document.location.protocol // 網絡協(xié)議(http:)
document.location.search // ?號后的部分
常用對象事件:
documeny.location.reload() //刷新網頁
document.location.reload(URL) //打開新的網頁
document.location.assign(URL) //打開新的網頁
document.location.replace(URL) //打開新的網頁
selection-選區(qū)子對象
document.selection