使用了如下形式imgArr.push({'index':this.index,'width':this.width,'height':this.height,'ratio':this.width/this.height});定义了数组,在调用的时候console imgArr显示正常,console imgArr[0]却显示Undefined;
这种问题如何解决?
自己又调试了下,确认了onload里生成的imgArr和调用的时候的先后顺序是调用的imgArr先console出来,然后才是onload里给imgArr赋值。
那么问题来了,如何让我顺利调用onload赋值后的imgArr???
以下为代码
(function (window) {
// 由于是第三方库,我们使用严格模式,尽可能发现潜在问题
'use strict';
function IfeAlbum() {
// 布局的枚举类型
this.LAYOUT = {
PUZZLE: 1, // 拼图布局
WATERFALL: 2, // 瀑布布局
BARREL: 3 // 木桶布局
};
// 公有变量可以写在这里
// this.xxx = ...
//默认参数
this._layout=2; //默认布局方式为瀑布流布局;
this._fullScreen=true; //默认允许点击后全屏显示图片
this._Barrel={
min:3,
max:6,
minHeight:300,
maxHeight:600
}
}
var album=document.getElementById('photo-album'),
browerH=document.documentElement.clientHeight || document.body.clientHeight,
browerW=document.documentElement.clientWidth || document.body.clientWidth;
var imgArr=[];
/**
* 初始化并设置相册
* 当相册原本包含图片时,该方法会替换原有图片
* @param {(string|string[])} image 一张图片的 URL 或多张图片 URL 组成的数组
* @param {object} option 配置项
*/
IfeAlbum.prototype.setImage = function (image, option) {
if (typeof image === 'string') {
// 包装成数组处理
this.setImage([image]);
return;
}
album.innerHTML="";
this.addImage(image);
};
/**
* 获取相册所有图像对应的 DOM 元素
* 可以不是 ,而是更外层的元素
* @return {HTMLElement[]} 相册所有图像对应的 DOM 元素组成的数组
*/
IfeAlbum.prototype.getImageDomElements = function() {
return album.querySelectorAll(".photo-thumbnail");
};
/**
* 向相册添加图片
* 在拼图布局下,根据图片数量重新计算布局方式;其他布局下向尾部追加图片
* @param {(string|string[])} image 一张图片的 URL 或多张图片 URL 组成的数组
*/
IfeAlbum.prototype.addImage = function (image) {
var count=image.length;
for (var i = image.length - 1; i >= 0; i--) {
//图片地址
var img=new Image();
img.index=i;
img.onload=function(){
imgArr.push({'index':this.index,'width':this.width,'height':this.height,'ratio':this.width/this.height});
imgArr.sort(function(a,b){
return a.index-b.index;
});
}
img.src=image[i];
//用新div包裹
var photoDiv=document.createElement('div');
photoDiv.className='photo-thumbnail';
photoDiv.appendChild(img);
//将其添加到容器内
album.appendChild(photoDiv);
}
var layout=this.getLayout();
switch(layout){
case 1:
this.puzzle();
break;
case 2:
this.waterfall();
break;
case 3:
this.barrel();
break;
}
};
/**
* 设置相册的布局
* @param {number} layout 布局值,IfeAlbum.LAYOUT 中的值
*/
IfeAlbum.prototype.setLayout = function (layout) {
if(typeof layout=="number" && (layout==1 || layout==2 || layout==3)){
this._layout=layout;
return false;
}
if(typeof layout=="string" && this.LAYOUT[layout]){
this._layout=this.LAYOUT[layout];
return false;
}
console.error("setLayout布局设置参数有误,请检查后重新设置");
};
/**
* 获取相册的布局
* @return {number} 布局枚举类型的值
*/
IfeAlbum.prototype.getLayout = function() {
console.log(this._layout);
return this._layout;
};
/**
* 设置木桶模式每行图片数的上下限
* @param {number} min 最少图片数(含)
* @param {number} max 最多图片数(含)
*/
IfeAlbum.prototype.setBarrelBin = function (min, max) {
// 注意异常情况的处理,做一个健壮的库
if (min === undefined || max === undefined || min > max) {
console.error('setBarrelBin的最少最多含图片数参数设置错误,请检查后重新输入');
return;
}
this._Barrel.min=min;
this._Barrel.max=max;
};
/**
* 获取木桶模式每行图片数的上限
* @return {number} 最多图片数(含)
*/
IfeAlbum.prototype.getBarrelBinMax = function () {
return this._Barrel.max;
};
/**
* 获取木桶模式每行图片数的下限
* @return {number} 最少图片数(含)
*/
IfeAlbum.prototype.getBarrelBinMin = function () {
return this._Barrel.min
};
/**
* 设置木桶模式每行高度的上下限,单位像素
* @param {number} min 最小高度
* @param {number} max 最大高度
*/
IfeAlbum.prototype.setBarrelHeight = function (min, max) {
if(min === undefined || max === undefined || min > max){
console.error('setBarrelHeight的最小最大高度参数设置错误,请检查后重新输入');
return;
}
this._Barrel.minHeight=min;
this._Barrel.maxHeight=max;
};
/**
* 获取木桶模式每行高度的上限
* @return {number} 最大高度
*/
IfeAlbum.prototype.getBarrelHeightMax = function () {
return this._Barrel.maxHeight;
};
/**
* 获取木桶模式每行高度的下限
* @return {number} 最小高度
*/
IfeAlbum.prototype.getBarrelHeightMin = function () {
return this._Barrel.minHeight;
};
IfeAlbum.prototype.barrel=function(){
var photoDiv=this.getImageDomElements(),
minHeight=this.getBarrelHeightMin(),
maxHeight=this.getBarrelHeightMax(),
min=this.getBarrelBinMin(),
max=this.getBarrelBinMax(),
photoArr=imgArr;
var i=photoDiv.length-1;
var imgRowArr=[];
console.log(imgArr,imgArr[0]);
//此处显示为Undefined
for (i;i >= 0; i--) {
var imgNow=photoArr[i];
var imgH=imgNow.height,
imgW=imgNow.width,
imgRatio=imgNow.ratio;
var browerW=browerW,browerH=browerH;
var rowH,rowW;
rowW+=imgW;
if(imgNum==0){
imgNum++;
if(imgH< minHeight) rowH=minHeight;
if(imgH>maxHeight) rowH=maxHeight;
imgW=rowH * imgRatio;
imgRowArr.push(imgNow);
}else if((rowW<browerW && imgNum<max)|| imgNum<min){
imgNum++;
imgH=rowH;
imgW=rowH*imgRatio;
imgRowArr.push(imgNow);
}else{
imgH=rowH;
imgW=rowH*imgRatio;
imgRowArr.push(imgNow);
var ratioRow=rowW/browerW;
rowH=rowH/ratioRow;
for (var j = 0; j < imgRowArr.length; j++) {
imgRowArr[i].height=rowH;
imgRowArr[i].width=rowH * imgRowArr[i].ratio;
}
imgNum=0;
imgRowArr=[];
rowH=0;
rowW=0;
}
}
}
// 实例化
if (typeof window.ifeAlbum === 'undefined') {
// 只有当未初始化时才实例化
window.ifeAlbum = new IfeAlbum();
}
}(window));
window.onload=function(){
ifeAlbum.setLayout(3);
ifeAlbum.setImage(["http://placehold.it/350x150","http://placehold.it/350x500","http://placehold.it/550x200","http://placehold.it/350x150"]);
}
加载图像是异步的,可以用回调(或者ES6 Promise,ES7 await/async)。
代码太多了,不看了哈哈~~
具体业务逻辑自己琢磨哈。