不固定图片宽高瀑布流_类百度图片的固定高度横向瀑布流js方法及纯css实现的方法记录...

b427df4c6d99?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

微信图片_20190117105118.png

纯css实现代码:

Document

div{

display: flex;/*显示模式设置为弹性盒子*/

flex-wrap: wrap;/*进行强制换行*/

}

div:after{

/*对最后一个伪元素进行最大限度伸缩*/

content: ' ';

flex-grow: 999999999999999999999999999999999999;

}

img{

height: 200px;/*高度*/

width: auto;

margin: 2px;

flex-grow: 1;/*进行按比例伸缩*/

object-fit: cover;/*进行裁切,并且图片按比例缩放*/

}

11a.jpg

bb.jpg

11a.jpg

bb.jpg11a.jpg

bb.jpg11a.jpg

bb.jpg11a.jpg

bb.jpg11a.jpg

bb.jpg

js实现代码及思路:

b427df4c6d99?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

微信图片_20190117142317.png

原理是木桶原理,把图片放进一个div计算当前排的宽度,如果大于的话,把最后一个pop掉,同时layout当前排,循环下去

Document

html,

body {

margin: 0;

padding: 0;

border: 0;

width: 100%;

}

.ct {

width: 90%;

margin: 0 auto;

}

/* 图片容器 */

.img-box {

float: left;

display: flex;

}

.imgSB {

margin-bottom: 5px;

overflow: hidden;

}

.imgS {

margin-right: 5px;

margin-bottom: 5px;

overflow: hidden;

}

.img-row{

display: flex;

flex-wrap: wrap;

}

.img-row .img-box:last-child{

flex:1;

}

/* 行容器 清楚子元素(图片容器)的浮动*/

.img-row::after {

content: "";

display: block;

clear: both;

}

var allImgUrl = [];

window.onload = function () {

let ct = document.querySelector(".ct");

let barrel = new Barrel(ct, 60, 200); // 100张图片数量, 指定每行的初始行高为100

}

var debounce = function (idle, action) {

var last

return function () {

var ctx = this,

args = arguments

clearTimeout(last)

last = setTimeout(function () {

action.apply(ctx, args)

}, idle)

}

}

window.onresize = debounce(100, function () {

let ct = document.querySelector(".ct");

ct.innerHTML = "";//删除子节点,resize的时候会比较烦,因为要先把之前的图片存好,删除子节点,然后执行重排..

let barrel = new Barrel(ct, 60, 200, 'resize'); // 100张图片数量, 指定每行的初始行高为100

})

function Barrel(ct, imgNum, height, type = 'new',ww=0) {

this.ct = ct; // 木桶布局容器的DOM节点

this.ww = ww;

this.type = type;

this.width = parseInt(window.getComputedStyle(ct, null).getPropertyValue("width")) - 20; // 行宽,预防滚动条出现预留20

console.log(this.width)

this.rowHeight = height; // 行高

this.imgArr = []; // 存放每行图片的数组

this.loadImg(imgNum);

}

Barrel.prototype = {

getImgUrls: function (imgNum) { //模拟后台获取的图片地址

console.log(this.type)

if (this.type !== 'resize') {

let imgUrls = [];

let colorArr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F"]; // 颜色数组[0-9, A-F],

// 该颜色数组生成与源代码稍有不同,在我的GitHub上是用for循环生成的

for (let i = 0; i < imgNum; i++) {

let imgWidth = Math.floor(Math.random() * 500 + 500); // 设定宽度500-1000

let imgHeight = Math.floor(Math.random() * 300 + 500); // 设定高度为300-800

let bgColor = textColor = ""; // 下面使用的是字符串拼接,每次使用都需要重新清空

for (let j = 0; j < 6; j++) {

bgColor += colorArr[Math.floor(Math.random() * 16)];

textColor += colorArr[Math.floor(Math.random() * 16)];

}

let url = "http://via.placeholder.com/" + imgWidth + "x" + imgHeight + "/" +

bgColor + "/" + textColor;

imgUrls.push(url);

}

allImgUrl = imgUrls;

return imgUrls;

} else {

// console.log(allImgUrl)

return allImgUrl;

}

},

loadImg: function (imgNum) {

let imgUrlsArr = this.getImgUrls(imgNum);

let _this = this; // 保存this指针的指向,方便调用属性及方法

for (let i = 0; i < imgNum; i++) {

let newImg = new Image(); // 新建图片对象

newImg.src = imgUrlsArr[i]; // 加载图片内容

let ww = 0;

newImg.onload = function () {

// Image对象加载了src后拥有宽高属性, imgInfo存储图片信息

let ratio = this.width / this.height;

// console.log(ratio)

let imgInfo = {

target: this, // 用来存放当前目标newImg,方便后续调用

height: _this.rowHeight,

width: ratio * _this.rowHeight, // 等比例缩放

ratio: ratio,

};

// 把加载完的图片加入渲染队列

_this.render(imgInfo,i);

}

}

},

render: function (imgInfo,i) {

this.imgArr.push(imgInfo);

// let ww = 0;

this.ww += imgInfo.width //性能优化,利用总ww来执行直接加

if (this.ww > this.width) {

let lastImg = this.imgArr.pop();

this.ww -= lastImg.width;

// 利用面积相等原则,来计算新的高度

let newHeight = this.width * this.rowHeight / this.ww;

let newRatio = this.width/this.ww;

this.layout(newHeight,newRatio);

// 放置完毕之前的图片之后,清空该图片队列

// 并将上一行溢出的图片 作为下一行的第一张

this.imgArr = [];

this.imgArr.push(lastImg);

this.ww = lastImg.width;//重置ww,但是要等于pop掉的那张图的width

}

// 定义该行图片宽度之和

// let wholeWidth = 0;

// this.imgArr.push(imgInfo);

// let wholePadding = 0;

// for (let i = 0; i < this.imgArr.length; i++) {

// wholeWidth += this.imgArr[i].width;

// wholePadding += 10;

// }

// // 如果该行加入的图片宽度大于了该行的宽度

// // 就需要弹出最后一张图片,并更改前面的图片大小比例

// if (wholeWidth > this.width) {

// // console.log(this.imgArr)

// let lastImg = this.imgArr.pop();

// wholeWidth -= lastImg.width;

// // 利用面积相等原则,来计算新的高度

// let newHeight = this.width * this.rowHeight / wholeWidth;

// let newRatio = this.width/wholeWidth;

// console.log(newRatio)

// this.layout(newHeight,newRatio);

// // 放置完毕之前的图片之后,清空该图片队列

// // 并将上一行溢出的图片 作为下一行的第一张

// this.imgArr = [];

// this.imgArr.push(lastImg);

// }

},

layout: function (newHeight,newRatio) {

// 一次只放一行, 所以只生成一个imgRow

let imgRow = document.createElement("div"); //可以选择一排排layout

imgRow.classList.add("img-row");//可以选择一排排layout

// console.log(this.imgArr)

// 一行包含若干个图片,所以需要若干个imgBox,并将图片加入其中

for (let i = 0; i < this.imgArr.length; i++) {

let imgBox = document.createElement("div");

imgBox.classList.add("img-box");

let imgS = document.createElement("div");

if (i === this.imgArr.length - 1) {

imgS.classList.add("imgSB");

} else {

imgS.classList.add("imgS");

}

let img = this.imgArr[i].target;

// 改变了高度之后宽度自己会跟着改变

// console.log(newRatio,this.imgArr[i].width)

img.style.width =parseInt(newRatio*this.imgArr[i].width)-5+'px';// 注意加"px",减掉一个margin-right的值

// img.style.height = newHeight - 5 + "px"; // 注意加"px",减掉一个margin-right的值

imgS.appendChild(img);

imgBox.appendChild(imgS);

imgRow.appendChild(imgBox);

// this.ct.appendChild(imgBox);//也可以一个个插入,反正都是float

}

// 先把图片加载到图片盒子里,然后加到图片列中,最后加到容器中

this.ct.appendChild(imgRow);//可以选择一排排layout

},

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值