我们先从获取图片说起
写在前边 JS 交互的问题呢,如果是小白,请看这里。
所有的JS ,都要写在
webViewDidFinishLoad 这个UIWebView的代理方法中。需要注入JS 。例如
获取image的JS
-(void)webViewDidFinishLoad:(UIWebView *)webView{
static NSString * const jsGetImages =
@"function getImages(){\
var objs = document.getElementsByTagName(\"img\");\
var imgScr = '';\
for(var i=0;i
你处理图片的点击事件需要在这个代理方法中
-(BOOL)webView:(UIWebView )webView shouldStartLoadWithRequest:(NSURLRequest )request navigationType:(UIWebViewNavigationType)navigationType;
JS 交互获取图片,需要执行JS。
@"function getImages(){\
var objs = document.getElementsByTagName(\"img\");\
var imgScr = '';\
for(var i=0;i
这样获取出来的是一个字符串。一个 以+号拼接的字符串,然后分解下就是全部的imageUrl.
这样你获取了所有的图片,然而并没有什么卵用。 < < !,那就有人说了,我想要的是图片点击,要获取到点击的图片的URL。 好吧。那么下边的JS ,完美的满足了您的需求。
[self.webView stringByEvaluatingJavaScriptFromString:@"function registerImageClickAction(){\
var imgs=document.getElementsByTagName('img');\
var length=imgs.length;\
for(var i=0;i
这样你在shouldStartLoadWithRequest 代理方法中,截获 名字是 image-preview的事件,获得的就是 当前点击的URL
if ([request.URL.scheme isEqualToString:@"image-preview"]) {
NSString* path = [request.URL.absoluteString substringFromIndex:[@"image-preview:" length]];
path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// path就是你要的imageUrl
}
那么好多人的需求到这里就结束了。 那么还有人说,我想要所有的图片。那么下边的js, 满足你
function getAllImageUrl(){\
var imgs = document.getElementsByTagName(\"img\");\
var urlArray = [];\
for (var i=0;i
得到的是一个数组。那么上边的三个JS, 满足了需求,很好,你可以去写你的代码了。那么这里如果想要继续深入了解的同学。请注意。以下内容是 性能优化的,不想了解的朋友直接 把上边的代码拿走就行。如果你还是没看懂那么参考下边这个文章:
http://www.jianshu.com/p/aa2f1dc8dff7
webview 是从网上加载的图片,然后显示这说明什么,说明图片已经在webview的内存缓存中了,那么,我们拿到图片,然后还得自己做缓存,就算是你用SD 。 也还是多了一步得从网上下载图片,这就造成了不必要的损耗,如果图片少,还没问题,如果,类似网易新闻,今日头条这样存在着大量的图片新闻的问题等。就会造成严重的内存问题。
博主找了很久,最后找到了。一个工具。RNCachingURLProtocol .获取内存中的缓存。具体原理的,webview的图片会用NSURLProtocol 来进行缓存,这个第三方 缓存图片到指定的文件夹
然后,读取指定文件夹来获取webview的缓存,当然,你也不需要了解太多,你拿去用就好 https://github.com/rnapier/RNCachingURLProtocol
当然。如果你特么想了解里边的东西,可以看看这个文章
http://blog.csdn.net/youcanping2008/article/details/9240487
或者是这个篇
http://www.jianshu.com/p/11664f0a69aa
那么,当你看完了, 以上几篇 ,还是不会用。请看下边。这么使用。。。。
在 didFinishLaunchingWithOptions 中,注册 [NSURLProtocol registerClass:[RNCachingURLProtocol class]];
然后在 shouldStartLoadWithRequest UIWebView的这个代理中直接获取就行了
NSString *fileName = [RNCachingURLProtocol cachePathForURLString:imgUrl];
RNCachedData *memoryCache = [NSKeyedUnarchiver unarchiveObjectWithFile:fileName];
memoryCache 这个就是内存缓存,那图片缓存呢。。看下边
imageView.image = [UIImage imageWithData:memoryCache.data];
这样就可以了。
以上就完美的解决了,交互图片,内存问题。 下边是扩展
如果有的朋友,想做一些动画效果,例如放大缩小,需要用到图片的frame。那么你可以看下去。使用下边的JS ,可以获得图片的frame
function getImageRect(i){\
var imgs = document.getElementsByTagName(\"img\");\
var rect;\
rect = imgs[i].getBoundingClientRect().left+\"::\";\
rect = rect+imgs[i].getBoundingClientRect().top+\"::\";\
rect = rect+imgs[i].width+\"::\";\
rect = rect+imgs[i].height;\
return rect;\
}\
这个获取的frame就是你需要的frame,一个相对位置,这个frame你不需要在convert ,你拿到的就是相对路径,是正确的,想具体理解的,百度 : getBoundingClientRect。
那么聪明的朋友已经获取了。点击图片的frame ,但是发现,怎么这个frame MMP的不对呢。动画都特么飞天上去了。位置都不对!!你是不是坑爹呢。请注意,我说了,这个frame是绝对正确的,那么问题出在哪?。大多数的webview 我们都会设置一个属性scalesPageToFit。自适应,就是这个属性导致我们得到的frame是有问题的,那么怎么解决的。
这样我们需要得到一个缩放的比率。然后把frame 乘以这个比率就可以了。代码如下
NSString *bodyWidth= [webView stringByEvaluatingJavaScriptFromString: @"document.body.scrollWidth"];
int widthOfBody = [bodyWidth intValue];
CGFloat initialScale = webView.frame.size.width/widthOfBody;
initialScale 就是这个比率 把frame *initialScale 就可以了。这样得到的frame就是 完美的。!
那么 继续扩展,哈哈哈哈
如果你想获得手指的点击位置那么下边的JS ,适合你
@"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\";};"
这样你在 处理时间的webview代理中 可以这么写
NSString *requestString = [[request URL] absoluteString];
NSArray *components = [requestString componentsSeparatedByString:@":"];
if ([components count] > 1 && [(NSString *)[components objectAtIndex:0]
isEqualToString:@"myweb"]) {
if([(NSString *)[components objectAtIndex:1] isEqualToString:@"touch"])
{
if ([(NSString *)[components objectAtIndex:2] isEqualToString:@"start"])
{
self.gesState = GESTURE_STATE_START;
NSLog(@"touch start!");
float ptX = [[components objectAtIndex:3]floatValue];
float ptY = [[components objectAtIndex:4]floatValue];
NSLog(@"touch point (%f, %f)", ptX, ptY);
上边的代码不能copy哈,你们自己写,
还有获取手指范围的图片等。具体参照 里边很全,但是他的demo 有问题。哪里有问题,自己找吧。
二维码识别的灯在这篇文章里都有写
http://www.jianshu.com/p/48e44fe67c1d
以上就是分解的 内容,下边,是博主的需求,点击webView 图片放大。只有一个图片,所以我只获取了一张图片。需要动画所以,获取了frame ,具体的代码,如下。小白如果需求跟我一样,直接复制吧
- (void)webViewDidFinishLoad:(UIWebView *)webView{
[self addJavaScript];
[webView stringByEvaluatingJavaScriptFromString:@"setImage();"];
// new for memory cleaning
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)addJavaScript {
NSString *clickGirl =
@"function setImage(){\
var imgs = document.getElementsByTagName(\"img\");\
for (var i=0;i
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest
*)request navigationType:(UIWebViewNavigationType)navigationType{
NSString *requestString = [[request URL] absoluteString];
NSArray *components = [requestString componentsSeparatedByString:@"::"];
if ([components[0] isEqualToString:@"clickgirl"]) {
NSString * imgUrl = components[1];
NSString *bodyWidth= [webView stringByEvaluatingJavaScriptFromString: @"document.body.scrollWidth"];
int widthOfBody = [bodyWidth intValue];
CGFloat initialScale = webView.frame.size.width/widthOfBody;
CGRect frame = CGRectMake([components[2] floatValue] *initialScale,([components[3] floatValue]) * initialScale +64, [components[4] floatValue] *initialScale , [components[5] floatValue] *initialScale);
NSString *fileName = [RNCachingURLProtocol cachePathForURLString:imgUrl];
RNCachedData *memoryCache = [NSKeyedUnarchiver unarchiveObjectWithFile:fileName];
UIImageView * imageView = [[UIImageView alloc] initWithFrame:frame];
if (memoryCache!=nil) {
imageView.image = [UIImage imageWithData:memoryCache.data];
// 获取了图片,你想干啥干啥
}else{
//基本用不到
[imageView sd_setImageWithURL:[NSURL URLWithString:imgUrl] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
}];
}
}
return YES;
}