Skip to content

Commit

Permalink
feat: 增加图片默认占位符 (#280)
Browse files Browse the repository at this point in the history
* feat: 增加图片默认布局占位

* feat: 更新jpeg拼写
  • Loading branch information
jennyliang220 authored and xuexb committed Apr 18, 2018
1 parent 3ffff5e commit 171d8ba
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 29 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mip",
"version": "1.0.80",
"version": "1.0.81",
"description": "mobile instant page",
"main": "dist/mip.js",
"dependencies": {},
Expand Down
181 changes: 153 additions & 28 deletions src/components/mip-img.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @file mip-img 图片组件
* @author wangpei07
* @author wangpei07,JennyL
*/

define(function (require) {
Expand All @@ -16,6 +16,28 @@ define(function (require) {
var viewer = require('viewer');
var errHandle;


// 取值根据 https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement
var imgAttributes = [
'alt',
'ismap',
'src',
'sizes',
'srcset',
'usemap',
'title'
];

// XXX: jpg 是 jpeg 的简写,在URL中都有出现,所以有相同的宽高比
var imgRatio = {
jpg: 1.33,
jpeg: 1.33,
png: 1,
gif: 1,
webp: 1,
other: 1
};

function getPopupImgPos(imgWidth, imgHeight) {
var width = viewport.getWidth();
var height = Math.round(width * imgHeight / imgWidth);
Expand All @@ -28,6 +50,25 @@ define(function (require) {
};
}

/**
* 从mip-img属性列表里获取属性
*
* @param {Object} attributes 参考: https://dom.spec.whatwg.org/#interface-namednodemap
* @return {Object} 属性列表JSON
* @example
* {
* "src": "http://xx.jpeg"
* "width": "720"
* }
*/
function getAttributeSet(attributes) {
var attrs = {};
Array.prototype.slice.apply(attributes).forEach(function (attr) {
attrs[attr.name] = attr.value;
});
return attrs;
}

var getImgOffset = function (img) {
var imgOffset = rect.getElementOffset(img);
return imgOffset;
Expand All @@ -36,8 +77,10 @@ define(function (require) {
// 创建弹层 dom
function createPopup(element, img) {
var mipPopWrap = document.querySelector('.mip-img-popUp-wrapper');
if (!!mipPopWrap && mipPopWrap.getAttribute('data-name') === 'mip-img-popUp-name'
&& mipPopWrap.parentNode.tagName.toLowerCase() === 'body') {
var popAttrLegal = mipPopWrap.getAttribute('data-name') === 'mip-img-popUp-name';
var inBody = mipPopWrap.parentNode.tagName.toLowerCase() === 'body';

if (!!mipPopWrap && popAttrLegal && inBody) {
mipPopWrap.querySelector('img').setAttribute('src', img.src);
return mipPopWrap;
}
Expand All @@ -50,9 +93,7 @@ define(function (require) {
popup.className = 'mip-img-popUp-wrapper';
popup.setAttribute('data-name', 'mip-img-popUp-name');

/*
* 创建图片预览图层
*/
// 创建图片预览图层
var popUpBg = document.createElement('div');
var innerImg = new Image();

Expand All @@ -79,13 +120,6 @@ define(function (require) {
return;
}

var onResize = function () {
imgOffset = getImgOffset(img);
css(popupImg, imgOffset);
naboo.animate(popupImg, getPopupImgPos(imgOffset.width, imgOffset.height)).start();
};
window.addEventListener('resize', onResize);

popup = createPopup(element, img);
popupBg = popup.querySelector('.mip-img-popUp-bg');
popupImg = popup.querySelector('img');
Expand All @@ -105,6 +139,13 @@ define(function (require) {

var imgOffset = getImgOffset(img);

var onResize = function () {
imgOffset = getImgOffset(img);
css(popupImg, imgOffset);
naboo.animate(popupImg, getPopupImgPos(imgOffset.width, imgOffset.height)).start();
};
window.addEventListener('resize', onResize);

css(popupImg, imgOffset);
css(popupBg, 'opacity', 1);
css(popup, 'display', 'block');
Expand All @@ -115,11 +156,13 @@ define(function (require) {
}, false);
}

var bindEvent = function (element, img) {
var bindLoad = function (element, img, mipEle) {
img.addEventListener('load', function () {
img.classList.remove('mip-img-loading');
element.classList.add('mip-img-loaded');
element.customElement.resourcesComplete();
});
mipEle.placeholder && mipEle.placeholder.remove();
}, false);

// Http header accept has 'image/webp', But browser don't support
// Set image visibility hidden in order to hidden extra style
Expand All @@ -132,7 +175,7 @@ define(function (require) {
*
* @param {HTMLElement} img image element
*/
function errorHandle (img) {
function errorHandle(img) {
if (!viewer.isIframed) {
return;
}
Expand All @@ -144,34 +187,117 @@ define(function (require) {
img.src = ele.href;
}
img.removeEventListener('error', errHandle);
};
}

function firstInviewCallback() {
var ele = this.element.querySelector('img');
if (ele) {
return;
}
var _img = new Image();
this.applyFillContent(_img, true);

var ele = this.element;
var img = new Image();

if (this.placeholder) {
img.classList.add('mip-img-loading');
}

this.applyFillContent(img, true);

var src = util.makeCacheUrl(ele.getAttribute('src'), 'img');
_img.src = src;
// transfer attributes from mip-img to img tag
this.attributes = getAttributeSet(this.element.attributes);
for (var k in this.attributes) {
if (this.attributes.hasOwnProperty(k) && imgAttributes.indexOf(k) > -1) {
if (k === 'src') {
// src attribute needs to be mip-cached
var imgsrc = util.makeCacheUrl(this.attributes.src, 'img');
img.setAttribute(k, imgsrc);
}
else if (k === 'srcset') {
var imgSrcset = this.attributes.srcset;
var reg = /[\w-/]+\.(jpg|jpeg|png|gif|webp|bmp|tiff) /g;
var srcArr = imgSrcset.replace(reg, function (url) {
return util.makeCacheUrl(url, 'img');
});
img.setAttribute('srcset', srcArr);

if (ele.getAttribute('alt')) {
_img.setAttribute('alt', ele.getAttribute('alt'));
}
else {
img.setAttribute(k, this.attributes[k]);
}
}
}

ele.appendChild(_img);

ele.appendChild(img);
if (ele.hasAttribute('popup')) {
bindPopup(ele, _img);
bindPopup(ele, img);
}

bindEvent(ele, _img);
bindLoad(ele, img, this);
}

customElem.prototype.firstInviewCallback = firstInviewCallback;

/**
* Placeholder 占位
*
* @class
* @param {Object} element 要添加占位的元素
*/
var Placeholder = function (element) {
this.targetEle = element;
};

Placeholder.prototype.init = function () {
this.imgType = this._getImgType(this.targetEle);
this._add(this.imgType);
};

Placeholder.prototype._add = function (type) {
var placeholder = this.placeholder = document.createElement('div');
placeholder.classList.add('mip-placeholder');
placeholder.classList.add('mip-placeholder-' + type);

this.targetEle.appendChild(placeholder);
};

Placeholder.prototype.remove = function () {
var parent = this.placeholder.parentElement;
parent && parent.removeChild(this.placeholder);
};

/**
* read img src/srcset and get img type
*
* @param {Object} ele target mip-img element
* @return {string} type of img
*/
Placeholder.prototype._getImgType = function (ele) {
var srcString = ele.getAttribute('src') || ele.getAttribute('srcset');
var imgType = '';
for (var type in imgRatio) {
if (srcString.match(type)) {
imgType = type;
}
}
return imgType || 'other';
};

customElem.prototype.createdCallback = function () {
var element = this.element;
var layoutAttr = element.getAttribute('layout');
var heightAttr = element.getAttribute('height');
if (layoutAttr || heightAttr) {
// do nothing, use layout as placeholder: Layout.applyLayout
}
else {
// 如果没有layout,则增加默认占位
this.placeholder = new Placeholder(element);
this.placeholder.init();
}
};

customElem.prototype.attributeChangedCallback = function (attributeName, oldValue, newValue, namespace) {
if (attributeName === 'src' && oldValue !== newValue) {
this.element.querySelector('img').src = newValue;
Expand All @@ -183,5 +309,4 @@ define(function (require) {
};

return customElem;

});
});
22 changes: 22 additions & 0 deletions src/less/mip-img.less
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,26 @@
mip-img {
display: block;
width: 100%;
/* XXX: remove small space between bottom of img and mip-img */
font-size: 0;
.mip-placeholder {
background: rgba(0,0,0,0.08);
width: 100%;
padding: 0;
}
.mip-img-loading {
position: absolute;
top: 0;
height: auto;
}
.mip-placeholder-jpg,
.mip-placeholder-jpeg {
padding-bottom: 75%;
}
.mip-placeholder-png,
.mip-placeholder-gif,
.mip-placeholder-webp,
.mip-placeholder-other {
padding-bottom: 100%;
}
}

0 comments on commit 171d8ba

Please sign in to comment.