iOS开发 UIWebView获取点击图片

来源:互联网 发布:恋爱 知乎 编辑:程序博客网 时间:2024/05/24 22:45

 首先要了解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

 oc-->js  stringByEvaluatingJavaScriptFromString,其参数是一NSString 字符串内容是js代码(这又可以是一个js函数、一句js代码或他们的组合),当js函数有返回值或一句js代码有值返回可通过stringByEvaluatingJavaScriptFromString的返回值获取

    js-->oc 利用webView的重定向原理(即重新在js中指定document.location的值,此为一url),只要在这个url字符串中按自定义的规则指定好所需调用oc中的函数和参数,然后通过OC中的shouldStartLoadWithRequest函数去捕获处理请求,处理完最后,如果js还想获取一些返回参数的话,同样让oc去通过stringByEvaluatingJavaScriptFromString调用刚js传过来的回调js函数就行,顺道把参数也一起传了。

   

    在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].onclick=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的逻辑更清晰,代码更简洁,为最佳选择。

0 0