One, foreword

In the development of news and information projects, news details function is the core of the project. Now we basically use the form of native + Webview to display news content. How to give users a better reading experience is a problem we need to consider.

This article focuses on the processing of pictures in news details:

  • Image placeholder before loading
  • Lazy loading of images
  • Local download, cache and display of images
  • Webview uses locally downloaded images for presentation

Two, technical implementation

2.1. Placeholder map before image loading

This functionality is easy to implement by replacing the SRC image address in the original tag with a local placeholder address.

  1. Use a regular<img.*? src\\s*=\\s*\"([^\"]+).*? >Match everything in the article<img/>Tag and the address of the image in SRC.
  2. Gets the address of the local placeholder map in the applicationplaceholderPathTo replace thesrcThe address of the picture indicated

2.2. Lazy loading of images

Considering the functional requirements and package volume, echo.js is finally selected to realize the lazy loading function of pictures in WebView.

However, in our technical design of news details, images need to be downloaded at the native end and cached locally. Echo.js is a lightweight image lazy loading library designed for the Web.

After exploring the usage, we found that we passed in a callback function when we initialized echo.js

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

This callback is a callback to whether the current is loading the image.

So can we use this callback function to tell native to download the image when we need to load the image? The following analysis of the echo.js source code reveals the timing of callback calls

if (elem.getAttribute('data-echo-background') ! == null) { elem.style.backgroundImage = "url(" + elem.getAttribute('data-echo-background') + ")"; } else { // elem.src= elem.getAttribute('data-echo'); This is the source code callback(elem, 'native-load-src'); Callback} if (! unload) { elem.removeAttribute('data-echo'); elem.removeAttribute('data-echo-background'); }Copy the code

Instead of assigning directly to SRC, trigger the callback callback and define an option to tell the receiver.

Back to the callback defined when initializing echo:

echo.init({ offset: 100, throttle: 500, debounce: false, callback: Function (element, op) {if (op === 'native-load-src'){// If (element, op === 'native-load-src'){// If (element, op === 'native-load-src'){// If (element, op === 'native-load-src'){ var data = { src: element.getAttribute('data-echo'), op: op, eleid: element.getAttribute('id'), }; / / / this is the js wkwebview method of communication with the native, uiwebview can use the corresponding way. Windows. Its. MessageHandlers. XXXXX. PostMessage ({" eventName ": "downImage", "body": data, }); }}});Copy the code

2.2.1. Use of echo.js

  • <img/>Labels need to be processed
<img id="fy-img-%@" class="lazy" SRC ="%@" data-echo="%@" /> data-echo: indicates the address of the remote image to be loaded. SRC: indicates the address of the placeholder image to be displayed. Class: Fixed lazy, which is the internal need ID for echo.js: this is optional, and is used to replace the SRC of the img file after the local image is downloadedCopy the code
  • Echo. Js needs to be initialized in the template HTML for news details
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, }); }}});Copy the code

2.3 local download, cache and display of images

As mentioned in the previous article, js side triggers the communication with Native terminal when the image is loaded, telling Native to download the image.

I use SDWebImage to download network pictures and cache them. The operation of downloading will not be described.

After downloading, get the address of the cached image and notify the JS side to replace SRC address.

Js side code:

Function renderLocalImage(SRC, id) {var ele = document.getelementbyid (id); var ele = document.getelementbyid (id); ele.src = src; }Copy the code

So far, the run run side is not perfect!!

Fixed an issue where WKWebview could not display sandbox images

Wait, how about the real phone or the display of the placeholder?

In my project, WkWebView is used to display news content, and images cached in sandbox cannot be displayed in WkWebView.

Solution: use GCDWebServer to give wkwebview the ability to access files in sandbox.

2.4. Webview uses locally downloaded images to display

  • The match was made earlier<img/>Tag and SRC content within the tagSDWebImageIf the SRC SRC already exists locally, replace it with the sandbox address (note the access service provided by GCDWebServer).
  • If there is no local, use the echo.js rule pair according to 2.2.1<img/>For processing

Third, summary

This is the realization of one of the functions in the news details, involving JS, image download, JS and OC interaction, HTML related knowledge.