新闻详情-图片懒加载及缓存

一、前言

开发新闻资讯类项目,新闻详情功能是项目的核心,现在基本采用原生+webview的形式来显示新闻内容,怎么给用户更好的阅读体验这是我们需要考虑的问题。

这篇文章主要针对新闻详情中图片的处理:

  • 图片加载前的占位图
  • 图片懒加载
  • 图片的本地下载、缓存、显示
  • webview使用本地下载好的图片来展示

二、技术实现

2.1、图片加载前的占位图

这个功能很好实现,使用本地占位图地址替换掉原始标签内src的图片地址就可以了。

  1. 使用正则匹配出文章内的所有标签以及src中的图片地址。
  2. 获取到本地占位图在应用内的地址placeholderPath来替换掉src所指的图片地址

2.2、图片懒加载

考虑到功能需求以及包体积的问题,最终选择了echo.js来实现webview内图片懒加载功能。

但是在我们对新闻详情的技术设计中图片的下载需要在native端进行并缓存在本地,echo.js是为web而设计的一个轻量级图片懒加载库。

通过对使用方法的研究,我们发现在初始化echo.js时让我们传入了一个callback的回调函数

echo.init({
        offset: 100,
        throttle: 500,
        debounce: false,
        callback: function (element, op) {
        }
    });

这个回调函数是对当前是否加载图片的回调。

那我们能不能在需要加载图片时通过这个回调函数告诉native端去下载图片呢?接下来对echo.js源码的分析发现callback调用的时机

 if (elem.getAttribute('data-echo-background') !== null) {
          elem.style.backgroundImage = "url(" + elem.getAttribute('data-echo-background') + ")";
        }
        else {
        // elem.src= elem.getAttribute('data-echo'); 这是源代码
          callback(elem, 'native-load-src'); // 自定义一个操作option, 回调到callback
        }
        if (!unload) {
          elem.removeAttribute('data-echo');
          elem.removeAttribute('data-echo-background');
        }

移除掉直接对src的直接赋值,改为触发callback回调并自定义一个option告诉接收方。

回到初始化echo时定义的回调:

echo.init({
        offset: 100,
        throttle: 500,
        debounce: false,
        callback: function (element, op) {
            if (op === 'native-load-src'){
                // 触发了图片加载操作,与native端通讯做图片下载操作。
                var data = {
                    src: element.getAttribute('data-echo'),
                    op: op,
                    eleid: element.getAttribute('id'),
                };
              
              /// 这是wkwebview中js与native端通讯的方式,uiwebview可以使用对应的方式. window.webkit.messageHandlers.xxxxx.postMessage({
                    "eventName": "downImage",
                    "body": data,
                });
            }
        }
    });

2.2.1、echo.js的使用

  • 标签需要做一定的处理


data-echo: 正常需要加载的远端图片地址
src: 需要显示的占位图地址
class: 固定填写lazy,是echo.js内部需要
id: 这个随意,为了处理本地图片下载完后替换img的src而存在
  • 新闻详情的模板html内需要初始化echo.js
echo.init({
        offset: 100,
        throttle: 500,
        debounce: false,
        callback: function (element, op) {
            if (op === 'native-load-src') {
                var data = {
                    src: element.getAttribute('data-echo'),
                    op: op,
                    eleid: element.getAttribute('id'),
                };
               window.webkit.messageHandlers.xxxxx.postMessage({
                    "eventName": "downImage",
                    "body": data,
                });
            }
        }
    });

2.3、图片的本地下载、缓存、显示

前文中提到js侧触发了图片加载时会与native端通讯,告诉native去下载图片。

本人是使用的SDWebImage来下载的网络图片并缓存,下载的操作就不赘述。

下载完成后获取缓存图片的地址,通知js端替换的src地址。

js端代码:

/// src 为本地图片的地址, id为给设置的id
function renderLocalImage(src, id) {
        var ele = document.getElementById(id);
        ele.src = src;
    }

至此,运行跑一边是不是完美!!

解决WKWebview中无法显示沙盒内图片的问题

等等,怎么在真机上还是显示的占位图??

多方面查找原因,我的项目中是使用的wkwebview来显示新闻内容,缓存在沙盒中的图片无法在 wkwebview中显示。

解决方案:
使用GCDWebServer给wkwebview提供访问沙盒内文件的能力。

2.4、webview使用本地下载好的图片来展示

  • 前文已经匹配出标签和标签内src的内容,通过SDWebImage提供的方法来判断这个src是否已经存在本地,如已经存在本地则直接替换成沙盒地址(注意通过GCDWebServer提供的访问服务)
  • 如果不存在本地,则按照2.2.1中echo.js使用规则对进行处理

三、总结

这是新闻详情中其中一个功能的实现,涉及了js、图片下载、js与oc交互、html相关的知识。
记录下我实现这个功能的过程,永远保持学习的态度。

你可能感兴趣的:(新闻详情-图片懒加载及缓存)