codeER.tec网页的东西iOS

iOS极简模式实现Webview网页图片原生预览

2017-06-13  本文已影响1610人  小小提莫酱
温暖.jpg

前言

最近的几个项目中都需要加载大量的HTML,需要将HTML中的图片在点击时实现原生预览。由于HTML的来源很复杂,包括有后台框架编辑的、第三方提供的、网络抓取的等等。所以只能采取获取HTML之后前端注入JS事件来触发图片点击事件,获取当前页面的所有图片地址。由于实现的原理很简单(两行代码),就不需要使用JavaScriptCore或者其他第三方框架了。

实现效果

HTMLImage.gif
框架整体介绍

实现原理

注入图片点击JS需要完成的功能
截取JS的点击事件解析URL
核心JS代码实现
// 通知 iPhone UIWebView 加载 url 对应的资源
//PhoneGap处理方式
function loadURL(url) {
    var iFrame;
    iFrame = document.createElement("iframe");
    iFrame.setAttribute("src", url);
    iFrame.setAttribute("style", "display:none;");
    iFrame.setAttribute("height", "0px");
    iFrame.setAttribute("width", "0px");
    iFrame.setAttribute("frameborder", "0");
    document.body.appendChild(iFrame);
    // 发起请求后这个 iFrame 就没用了,所以把它从 dom 上移除掉
    iFrame.parentNode.removeChild(iFrame);
    iFrame = null;
}
function zwPreviewImageClickAction(){
    var imgs=document.getElementsByTagName('img');
    var length=imgs.length;
    var allSrc='';
    for(var i=0;i<length;i++){
        var img=imgs[i];
        var imaSrc = '';
        if (img.src.length){
            imaSrc = img.src;
        }else{
            imaSrc = img.getAttribute('data-original-src');
        }
        if (allSrc.length) {
            allSrc = allSrc+'^^^'+imaSrc;
        }else{
            allSrc = imaSrc;
        }
    }
    for(var i=0;i<length;i++){
        var img=imgs[i];
        img.onclick=function(){
//            window.location.href='zw-image-preview:'+allSrc + '###'+this.src;
            loadURL("zw-image-preview:"+allSrc+ '###'+this.src);
        }
    }
}
zwPreviewImageClickAction();
截取JS事件并解析URL
  1. UIWebView在shouldStartLoadWithRequest代理方法中
  2. WKWebView在decidePolicyForNavigationAction代理方法中
if ([request.URL.scheme isEqualToString:@"zw-image-preview"]) {
        NSString *urlPath = [request.URL.absoluteString substringFromIndex:[@"zw-image-preview:" length]];
        NSArray *mixURLArray = [urlPath componentsSeparatedByString:@"###"];
        //图片地址合集
        NSString *allImageURL = [mixURLArray firstObject];
        //当前实际点击图片的地址
        NSString *indexImageURL = [mixURLArray lastObject];
    }

实际项目中遇到的问题

封装JS与URL解析

为了避免重复调用,快速实现功能。对上述功能做了简单的封装。

-(void)webViewDidFinishLoad:(UIWebView *)webView{
    self.htmlSDK = [ZWHTMLSDK zw_loadBridgeJSWebview:webView];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    if ([self.htmlSDK zw_handlePreviewImageRequest:request]) {
        return NO;
    }
    return YES;
}
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    self.htmlSDK = [ZWHTMLSDK zw_loadBridgeJSWebview:webView];
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    decisionHandler(WKNavigationActionPolicyAllow);
    [self.htmlSDK zw_handlePreviewImageRequest:navigationAction.request];
}
效果展示
normalPreview.gif
SDK源码解析
self.htmlSDK = [ZWHTMLSDK zw_loadBridgeJSWebview:webView];
self.htmlSDK = [ZWHTMLSDK zw_loadStandardBridgeJSWebview:webView];
ZWHTMLOption *option = [[ZWHTMLOption alloc] init];
  option.getAllImageCoreJS = OPTION_StandardCoreJS;
  option.filterURL = @[@"logo",@"avaters"];
  self.htmlSDK = [ZWHTMLSDK zw_loadBridgeJSWebview:webView withOption:option];
ZWHTMLOption *option = [[ZWHTMLOption alloc] init];
  option.zwPreviewJS = @"自定义的JS";
  self.htmlSDK = [ZWHTMLSDK zw_loadBridgeJSWebview:webView withOption:option];

图片预览显示

//预览视图、已集成SDK中
ZWPreviewImageView *showView = [ZWPreviewImageView showImageWithArray:allImageArray withShowIndex:index];
[showView showRootWindow];
self.htmlSDK.blockHandlePreview = ^(NSArray *allImageArray, NSInteger index) {
        //自定义图片预览
    };

如何使用SDK

强烈建议您使用pod导入,节省导入依赖的时间。

pod 'ZWHTMLImage',       '~> 0.0.2'

依赖ZWPhotoPreview图片显示框架。

#import "ZWHTMLSDK.h"

关于图片保存权限

Privacy - Photo Library Additions Usage Description

源码

源码放在GitHub上,欢迎指正,记得star哦!

v0.0.2版本更新记录

v0.0.1版本更新记录

上一篇 下一篇

猜你喜欢

热点阅读