nimble-ui
Version:
147 lines (142 loc) • 4.62 kB
JavaScript
import { LazyLoadImg, extend, getBackData, onRender } from 'nimble-lib';
import './style.scss';
// import errorSrc from './imgs/hu.svg';
import errorSrc from './imgs/log-min.png';
let _lazy = {
name: 'lazy',
/**
* 初始化图片懒加载
*
* @export
* @param {Object} options 选项
* @return {Object}
*/
initLazy (options) {
options = options || {};
options = options.Lazy || options;
let _options = extend({}, {
attempt: 1,
loadingSrc: errorSrc, // 加载时的图片地址
errorSrc: errorSrc, // 出错后的图片地址
imgFilter: null, // 图片url过滤器
isWrap: true, // 加载时是否加包裹元素
lazyWrapCla: 'nus_lazy-imgBox', // 包裹的class
lazyCla: 'nus_lazy-img', // 当前加载项的class
isSetStyle: true, // 是否设置图片style
getImageInfo(imgUrl) { // 获取图片信息
return {
src: imgUrl
};
}
}, options);
let $LazyImg = LazyLoadImg(_options);
let back = {
name: 'lazy',
bind (el, binding) {
let val = binding.value;
if (val && (val.width || val.height)) {
getData(binding, el).then((data) => {
$LazyImg.defaultOption.imgRenderer({
el: el,
type: 'init',
options: extend({}, _options, data)
});
$LazyImg.push(el, data);
});
}
},
inserted (el, binding) { // 保证没传宽度的时候能取到宽度
let val = binding.value;
if (!(val && (val.width || val.height))) {
onRender(el, (_el) => {
if (_el) {
getData(binding, _el).then((data) => {
$LazyImg.update(_el, data);
});
}
}, {
count: 20,
time: 50
});
}
},
update (el, binding) {
getData(binding, el).then((data) => {
$LazyImg.update(el, data);
});
},
unbind (el) {
$LazyImg.remove(el);
}
};
return {
directive: back,
Lazy: $LazyImg
};
/**
* 设置大小
*
* @param {Object} binding 指令数据
* @param {HTMLElement} el 图片的父节点
* @return {Promise}
*/
function getData(binding, el) {
let _value = formatValue(binding.value);
return new Promise((resolve, reject) => {
let _parent = el.parentNode;
getBackData(_options.getImageInfo, [_value.src, extend({
width: _parent,
height: _parent
}, _value)]).then((res) => {
let _res = Object.assign({}, _value, res, serializeModifiers(binding.modifiers));
if (el.src === res.src || el._src === res.src) {
return;
}
resolve(_res);
});
});
}
/**
* 序列化modifiers
* @param {Object} modifiers 修饰符
* @return {Object}
*/
function serializeModifiers(modifiers) {
let res = {};
if (modifiers) {
if (modifiers.poster) {
res.srcAttr = 'poster';
} else if (modifiers.background || modifiers.backgroundImage || modifiers.bg) {
res.srcAttr = 'background';
}
}
return res;
}
/**
* 格式化value参数
*
* @param {*} val 参数
* @return {Object}
*/
function formatValue(val) {
let res = val;
if (typeof val === 'string') {
res = {
src: val
};
}
return res;
}
}
};
/**
* 图片懒加载
*
* @export
* @param {Object} options 选项
* @return {Object}
*/
export default function VueLazy (options) {
let res = _lazy.initLazy(options);
return res;
}