首先要了解iOS开发js与Objective-C交互的知识:参考:《UIWebView与JavaScript的交互》 http://blog.sina.com.cn/s/blog_74e9d98d010199jc.html 、《 iOS开发之Objective-C与JavaScript的交互》http://blog.csdn.net/ly20091130/article/details/42169931
在webView中点击图片需获取到图片链接,然后进行查看大图或者是下载操作,关键在于如何获取到当前被点击的图片的链接。目前掌握的方式有两种(经比较第二种方式比较好):
1、网页整体添加触摸监听。 利用j s对整个网页添加Touch监听(document的ontouchstart、ontouchmove、ontouchend),获取触摸坐标拼凑成链接并重定向到该链接,webView会在委托方法webView:shouldStartLoadWithRequest:navigationType:中拿到该链接以进行处理。根据触摸的开始start、移动move和结束end进行判断是点击还是滑动(可以判断start和end中间是否有move),在触摸结束end并且上一状态为触摸开始start并未经历触摸移动move时判定为点击事件,用触摸开始时获取到的坐标点来获取网页该点的图片资源的链接。
2、注入js方法为图片资源添加点击跳转。先注入一个为页面中所有图片资源添加点击(noclick)跳转的js方法,然后调用运行该js方法,这样就能在图片被点击后进行跳转时获取到该图片的链接。
刚开始实现这个功能时在搜到了第一种方式,可以完美满足需求。后和安卓的同事讨论各自实现方式,发现第二中方式显然逻辑更简洁清晰,刚实现了第二中方式,期间走了点弯路--只注入了js方法并未调用,现把两种方式都记录下来,两种方式的代码如下。
方式1代码:
#pragma mark - UIWebViewDelegate
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
//js方法网页整体添加触摸监听
static NSString* const kTouchJavaScriptString=
@"document.ontouchstart=function(event){\
x=event.targetTouches[0].clientX;\
y=event.targetTouches[0].clientY;\
document.location=\"myweb:touch:start:\"+x+\":\"+y;};\
document.ontouchmove=function(event){\
x=event.targetTouches[0].clientX;\
y=event.targetTouches[0].clientY;\
document.location=\"myweb:touch:move:\"+x+\":\"+y;};\
document.ontouchcancel=function(event){\
document.location=\"myweb:touch:cancel\";};\
document.ontouchend=function(event){\
document.location=\"myweb:touch:end\";};";
[_pWebView stringByEvaluatingJavaScriptFromString:kTouchJavaScriptString];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
static int lastEvent = 0;//用来记录上一次的触摸事件 0:无事件 1:start、 2:move 、3:end
static float ptX = 0.0f;//触摸开始点的 x
static float ptY = 0.0f;//触摸开始点的 y
NSArray *components = [requestString componentsSeparatedByString:@":"];
if ([components count] > 1 && [(NSString *)[components objectAtIndex:0]
isEqualToString:@"myweb"]) {
if([(NSString *)[components objectAtIndex:1] isEqualToString:@"touch"]){
NSLog(@"you are touching!");
if ([(NSString *)[components objectAtIndex:2] isEqualToString:@"start"]) {
NSLog(@"touch start!");
lastEvent = 1;//记录当前为触摸开始
ptX = [[components objectAtIndex:3]floatValue];//记录触摸开始点x
ptY = [[components objectAtIndex:4]floatValue];//记录触摸开始点y
NSLog(@"touch point (%f, %f)", ptX, ptY);
} else if ([(NSString *)[components objectAtIndex:2] isEqualToString:@"move"]) {
NSLog(@"you are move");
lastEvent =2;//记录当前为触摸移动
} else if ([(NSString*)[components objectAtIndex:2]isEqualToString:@"end"]) {
if (lastEvent==1) {
NSString *js = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).tagName", ptX, ptY];
NSString * tagName = [_pWebView stringByEvaluatingJavaScriptFromString:js];
if ([tagName isEqualToString:@"IMG"]) {
NSString * jsGetUrl = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", ptX, ptY];
NSString *imageUrl = [_pWebView stringByEvaluatingJavaScriptFromString:jsGetUrl];
NSLog(@"image url=%@", imageUrl);
[self showImageWithURLStr:imageUrl];//显示图片
}
}
NSLog(@"touch end");
lastEvent = 0;//触摸结束 重置为无点击事件
}
}
return NO;
}
return YES;
}
方式2代码:
#pragma mark - UIWebViewDelegate
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
//js方法遍历图片添加点击事件 返回图片个数
static NSString * const jsGetImages =
@"function getImages(){\
var objs = document.getElementsByTagName(\"img\");\
for(var i=0;i<objs.length;i++){\
objs[i].οnclick=function(){\
document.location=\"myweb:imageClick:\"+this.src;\
};\
};\
return objs.length;\
};";
[_pWebView stringByEvaluatingJavaScriptFromString:jsGetImages];//注入js方法
//注入自定义的js方法后别忘了调用 否则不会生效
NSString *resurlt = [_pWebView stringByEvaluatingJavaScriptFromString:@"getImages()"];//调用js方法
NSLog(@"%@ %s jsMehtods_result = %@",self.class,__func__,resurlt);
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *requestString = [[request URL] absoluteString];
NSLog(@"%@",requestString);
if ([requestString hasPrefix:@"myweb:imageClick:"]) {
NSString *imageUrl = [requestString substringFromIndex:@"myweb:imageClick:".length];
NSLog(@"image url=%@", imageUrl);
[self showImageWithURLStr:imageUrl];//显示图片
return NO;
}
return YES;
}
结论:明显方式2的逻辑更清晰,代码更简洁,为最佳选择。