react lazyload

思路: 
DOM加载时,<img> 标签里,添加data-src路径 = src 路径, src路径 = 本地默认图片路径,
DOM加载完成后,监听页面可视区域,有data-src时,就将src路径替换成data-src路径,进行图片加载。

/**
* 页面
*/
import LazyLoad from '../libs/LazyLoad';
imglazyload(htmlStr) {
let imgList = [];
const src = [];
const dataSrc = [];
const imgSrc = [];
let newHtmlStr = htmlStr;
imgList = newHtmlStr.match(/<img [^>]* src=['"]([^'"]+)[^>]*>/gi, function (match, capture) {
});
/*
匹配图片(g表示匹配所有结果i表示区分大小写)
const imgReg = /<img.*>/gi;
匹配src属性
*/
const srcReg = / src=['"]?([^'"]*)['"]?/gi;
/* 匹配data-src属性
var dataSrcReg = / data-src=['"]?([^'"]*)['"]?/gi; */
if (imgList) {
for (let i = 0; i < imgList.length; i++) {
src[i] = imgList[i].match(srcReg);
/* dataSrc[i] = imgList[i].match(dataSrcReg); */
/* dataSrc赋值src,且不随src的改变而改变 */
dataSrc[i] = src[i].slice(0);
/* 替换src属性 */
dataSrc[i][0] = dataSrc[i][0].replace(/src/gi, 'data-src');
/* 组装 src data-src */
imgSrc[i] = '<img class="news_img_back"' + dataSrc[i][0];
/* 获取图片地址 */
newHtmlStr = newHtmlStr.replace(/<img [^>]* src=['"]?([^'"]*)['"]?/gi, imgSrc[i]);
}
      //newHtmlStr = newHtmlStr.replace(/(<img[^>]+)src=(['"]?([^'"]*)['"]?)/gi, "$1 data-src= $2"); //功能与绿色字体部分相同
        /* 进程的最后执行,即在return之后执行 */
setTimeout(LazyLoad, 0);
}
return newHtmlStr;
}
render(){
  <div dangerouslySetInnerHTML={{ __html: this.imglazyload(news.content)}} />
}
/* lazyload.js 
* expects a list of:
* `<img src="blank.gif" data-src="my_image.png" width="600" height="400" class="lazy">`
*/
const $q = function (q, res) {
if (document.querySelectorAll) {
res = document.querySelectorAll(q);
} else {
const d = document, a = d.styleSheets[0] || d.createStyleSheet();
a.addRule(q, 'f:b');
for (let l = d.all, b = 0, c = [], f = l.length; b < f; b++) {
l[b].currentStyle.f && c.push(l[b]);
}
a.removeRule(0);
res = c;
}
return res;
},
addEventListener = function (evt, fn) {
window.addEventListener ? window.addEventListener(evt, fn, false)
: (window.attachEvent) ? this.attachEvent('on' + evt, fn)
: window['on' + evt] = fn;
},
_has = function (obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
};
/* src 与data-src 替换 */
function loadImage(el, fn) {
const img = new Image(),
/* getAttribute() 方法返回指定属性名的属性值 */
src = el.getAttribute('data-src');
/* img.onload: img元素加载完后执行 */
img.onload = function () {
if (!! el.parent) {
el.parent.replaceChild(img, el);
} else {
el.src = src;
}
fn ? fn() : null;
};
img.src = src;
}
function elementInViewport(el) {
/* 获取元素各边距离页面各边的距离 */
const rect = el.getBoundingClientRect();
return (
rect.top >= 0
&& rect.left >= 0
&& rect.top <= (window.innerHeight || document.documentElement.clientHeight)
);
}
export default function () {
const images = [],
query = $q('[data-src]'),
processScroll = function () {
for (let i = 0; i < images.length; i++) {
if (elementInViewport(images[i])) {
loadImage(images[i], function () {
images.splice(i, i);
});
}
}
};
/* Array.prototype.slice.call is not callable under our lovely IE8 */
for (let i = 0; i < query.length; i++) {
images.push(query[i]);
}
processScroll();
addEventListener('scroll', processScroll);
}