html木桶布局,木桶布局 实现

57ac6677dd9c

百度图片

图片来自 百度图片

像这样高度一样,而宽度不同的布局方式称之为木桶布局。它有几个鲜明的特点: 每行的图片高度一致;每行的图片都是占满的。

如何实现木桶布局 之 整体思路

我们需要先拥有一些素材(图片), 并且将这些图片横向摆放到页面上。假如我现在有100张图片,并且编号1~100, 它们的宽高都不是固定的。现在我们需要将图片都摆放到目标页面上。

首先,我们每行的高度是事先设定的,所以我们在把图片放入每一行(row)的时候,需要先调整图片的大小(等比例放大或缩小)使得图片的高度与行容器的高度一致 —— 即下图中的蓝色方框。

其中: 橙色方框代表图片(假设已和蓝色方框等高), 黑色数字代表图片编号。

依次往行容器中放置等比例大小调整过的图片,①号图片,②号图片,...,一直到⑤号图片,发现⑤号图片它放不下了。这时候我们就需要把这个⑤号图片放到下一行的开头,并且再次调整图片大小,使得第一行中的①号-④号图片能够撑满第一行。该次调整主要是调整图片的高度,使得其宽度能够自适应撑满该行。

如果测量一下百度图片每行的高度就会发现: 每行高度基本相等,但有几像素的差距。

57ac6677dd9c

木桶布局原理

然后重复上述步骤,直至图片摆放完毕。

木桶布局代码实现 之 具体步骤

从HTML、CSS、JS部分依次实现。

大概有个结构,就是先有一个固定宽度的父容器,与若干个(数量未定的)行容器来盛放每行的图片数量,然后每行有若干个图片容器来盛放图片。

父子关系(父 > 子): 固定宽度的父容器 (" .ct ") > 行容器(" .img-row ") > 图片容器(" .img-box ")

对应上图(木桶布局原理)为: 红色方框 > 蓝色方框 > 橙色方框

/* CSS */

/* 页面布局容器*/

.ct {

width: 1000px;

margin: 0 auto;

}

/* 图片容器 */

.img-box {

float: left;

}

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

.img-row::after {

content: "";

display: block;

clear: both;

}

JS代码

这里采用构造函数创建对象的方式来写这段代码,注意按照约定构造函数的首字母要大写。创建一个新对象,然后将构造函数的作用域赋给新对象,调用构造函数中的方法。

函数名声明为 Barrel ,意为木桶。然后就要确定有哪些属性和方法。在理解了思路步骤的前提下,可以构思需要哪些属性、方法以及它们的作用。

属性:

每行图片的高度固定: rowHeight, 行高

拥有一个固定的容器: DOM对象,一个容器 命名为 .ct。 还应该有行容器和图片容器,但是由于这两个容器内容数量不固定,所以在布局的时候再创建

行容器的宽度: width, 获取ct的宽度

存放每行图片的数组: imgArr[]。每次把加载的图片压入该数组,判断该行是否超出宽度。

方法:

拥有素材图片 : 通过getImgUrls()方法来获取图片链接,(或从数据库中获取图片)。这里是通过访问https://placeholder.com/ 网站来获取代码,具体后述

加载图片信息: loadImg()方法来加载图片,以便获取图片信息,

渲染图片队列: render() 改变图片的比例大小,计算一行可以放置多少个图片

放置图片位置: layout() 将改变完大小的图片放置到页面上,append到对应的DOM元素节点上。具体关系对应前面的父子关系即可

初步的代码结构就如下所示:

function Barrel(ct, imgNum, height) {

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

this.width = parseInt(window.getComputedStyle(ct, null).getPropertyValue("width")); // 行宽,由于获取到的值是string: 1000px 所以转化为数值 1000

this.rowHeight = height; // 行高

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

this.loadImg(imgNum);

}

Barrel.prototype = {

getImgUrls: function(){},

loadImg: function(){},

render: function(){},

layout: function(){}

}

方法实现:

getImgUrls()方法:首先可以访问该网站 ,可以获取到占位图片,可以看到获取占位图片的格式 : http://via.placeholder.com/width x height /ffffff/00000/ , width与height分别代表图片的宽高,fffff是图片的背景颜色,000000是图片的文本颜色。

随机生成图片的大小(宽高限定一个范围),背景颜色与文本颜色。这里添加一个参数,imgNum:确定需要图片的数量。最后返回包含这些图片链接的一个数组

getImgUrls: function(imgNum){

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()*50+50); // 设定宽度50-100

let imgHeight = Math.floor(Math.random()*30+50); // 设定高度为30-80

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);

}

return imgUrls;

}

loadImg() 方法:用来加载图片,图片来源就从已有素材中寻找。即getImgUrls()

在这个方法中,需要做的就是获取图片信息(宽高,src等)并改变大小,高度与行高一致,宽度等比例改变。并且将信息存储起来,等每张图片加载完毕后就加入渲染排列图片的队列中。

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]; // 加载图片内容

newImg.onload = function(){

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

let ratio = this.width / this.height;

let imgInfo = {

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

height: _this.rowHeight,

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

ratio: ratio,

};

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

_this.render(imgInfo);

}

}

},

render()方法:渲染队列的方法,主要是判断图片能否放在一行上(每次把图片加入到imgArr队列中就可判断长度),并当图片符合占满一行的条件时,将最后一张图片放到下一行,并记录需要改变的图片比例交由layout()方法更改。

render: function(imgInfo){

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

let wholeWidth = 0;

this.imgArr.push(imgInfo);

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

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

}

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

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

if(wholeWidth > this.width){

let lastImg = this.imgArr.pop();

wholeWidth -= lastImg.width;

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

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

this.layout(newHeight);

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

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

this.imgArr = [];

this.imgArr.push(lastImg);

}

}

layout()方法:获得newHeight参数,是图片的新高度,改变该行图片的高度,使得这些图片自适应改变宽度之后能占满该行。也就是说这个木桶布局的高度会发生变化 与之前设定的this.rowHeight相近但不相等。

之后创建节点,并把修改好的图片依次加入到创建好的节点上,然后添加到页面中。

layout: function(newHeight){

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

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

imgRow.classList.add("img-row");

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

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

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

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

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

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

img.style.height = newHeight + "px"; // 注意加"px"

imgBox.appendChild(img);

imgRow.appendChild(imgBox);

}

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

this.ct.appendChild(imgRow);

}

最后便是两行代码来运行这段程序

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

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

效果预览及代码地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/443012.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何自己塑封_全球市场三足鼎立,国内半导体封测业如何实现可持续发展?

由于全球半导体市场规模不断增长&#xff0c;终端电子产品需求旺盛&#xff0c;国内半导体封装测试产业迎来了良好的发展机遇。国内半导体封装测试产业如何实现高质量、可持续发展?一时间&#xff0c;半导体封装测试产业再起热议。全球封装测试市场三足鼎立我国半导体封装测试…

博途中用的是c吗_一只“66 鸭”离奇出走,只为助蛋宝宝C位出道

作者 | 欧阳睿 来源 | 4A广告文案对于喜爱蛋黄酥的粉丝来说&#xff0c;一定知道轩妈蛋黄酥&#xff0c;这个在南宁土生土长的蛋黄酥品牌&#xff0c;2015年公司才刚刚成立&#xff0c;如今已坐拥超高人气和口碑&#xff0c;成长为全网类目的TOP1&#xff0c;就连李佳琦也强…

尼奥机器人不能手机绑定_微信绑定的手机号,如果手机号停用,是不是微信也不能用了?...

风水转运算命师未卜先知、指点迷津&#xff0c;助你顺风顺水&#xff01;商务合作qq&#xff1a;2770794800如果小编现在问你&#xff1f;你在干什么&#xff1f;那么是不是很多人都会说&#xff1a;当然是在刷手机了&#xff01;我们现在生活中最经常使用的就是手机了&#xf…

吸顶那个叫什么_为什么我家吸顶灯开灯后一闪一闪的

前不久&#xff0c;笔者看到网络上有网友在问&#xff1a;为什么我家的吸顶灯开灯后一闪一闪的&#xff0c;关灯后闪一会才会灭&#xff01;对于这个问题&#xff0c;笔者发现有好多网友在问。我们给出的方法和原则就是&#xff1a;哪里里坏了换哪里&#xff01; 那么&#xff…

计算机声卡怎么启动不了,三大方法助你解决声卡故障问题!

电脑声卡坏了怎么办?可能大家平时会碰到这个问题&#xff0c;别紧张&#xff0c;电脑声卡故障的原因无非就是那么几个&#xff0c;下面让小编带大家一起分析分析电脑声卡故障的原因以及处理办法。造成电脑声卡故障的原因主要有三种&#xff0c;一是相关服务未开启&#xff0c;…

我的世界服务器自定义欢迎界面,我的世界启动界面如何修改 diy修改启动界面攻略...

来源&#xff1a;网络我的世界怎么修改界面描述如何修改描述&#xff0c;是不是很多小伙伴们都不了解呢&#xff1f;今天Minecraft中文分享站小编就来给大家介绍一下&#xff0c;还不是很清楚相关内容的小伙伴抓紧了&#xff0c;希望这篇攻略对大家有帮助~&#xff01;我的世界…

腾讯云服务器数据盘买多了,腾讯云Windows云服务器数据盘分区和格式化

Windows2008_64位系统手动格式化小于2TB数据盘操作指引新购买的Windows云服务器&#xff0c;数据盘未做分区和格式化&#xff0c;无法使用。请根据以下步骤手动对数据盘进行分区以及格式化。暂不支持对Windows云服务器进行自动格式化。1. 进入数据盘分区界面登录Windows云服务器…

dataset的去重计数 g2_向工程渣土运输车辆计数 漏洞损失说“不”

基建越来越扩张的今天&#xff0c;很多工地还在人工计数管理&#xff0c;漏洞巨大&#xff0c;不远改变思维&#xff0c;总觉得损失一点也没有什么&#xff0c;现在开始逐渐推行智慧工地渣土运输管理&#xff0c;没有跟上步伐的&#xff0c;迟早会被被市场和“甲方爸爸”抛弃&a…

服务器虚拟化底层系统安装,Hyper-V是底层的虚拟机程序,位于操作系统和硬件之间,很薄一层...

今天介绍Hyper-V是底层的虚拟机程序&#xff0c;Windows server 2008 R2如何启动Hyper-V虚拟机。小伙伴们可能不一定了解&#xff0c;Hyper-V是微软的一款虚拟化产品&#xff0c;是微软第一个采用类似VMWare和Citrix Xen一样的基于Hypervisor的技术。通过Hyper-V功能&#xff0…

显示三维图片序列_SLAM结合三维检测

11.11---11.17​ 在此前一周进行yolo与cube slam整合的时候&#xff0c;采用ros通信的方式。存在两个问题&#xff1a;一个是darknet检测不到目标&#xff0c;就不对外发布检测结果&#xff0c;会造成检测结果和图片序列对不上。另一个问题是图片发布给darknet和cube slam的时间…

cc穿盾并发脚本_敢不敢模拟超过 5 万的并发用户?

阅读本文大概需要 6 分钟。来自&#xff1a;http://t.cn/ES7KBkW本文将从负载测试的角度&#xff0c;描述了做一次流畅的 5 万用户并发测试需要做的事情。你可以在本文的结尾部分看到讨论的记录。快速的步骤概要&#xff1a;编写你的脚本使用 JMeter 进行本地测试BlazeMeter 沙…

tomcat上传文件到不同服务器,使用SpringMVC进行跨服务器上传文件出现的那些坑

[1] 405 Method Not Allowed原因是因为Servlet默认是只读的&#xff0c;也就是写不进去(文件上传不过来)所以要在文件服务器的 web.xml 对 Servlet 进行配置defaultServletorg.apache.catalina.servlets.DefaultServletdebug0readonlyfalselistingsfalse1defaultServlet/这里可…

confluence添加用户_玩转Confluence插件开发插件模块配置文件介绍(04)

上一章节我们介绍了测试模块的配置文件,这一章节我们介绍插件本身的配置文件,这个是我们部署插件真正用到的. 文件的位置位于项目主目录中的/src/main/resources目录中.插件配置文件介绍插件描述文件的根元素<atlassian-plugin key"${project.groupId}.${project.artif…

nodejs复制服务器文件,nodejs文件夹深层复制功能

nodejs文件夹深层复制功能发布时间&#xff1a;2020-10-16 16:35:07来源&#xff1a;脚本之家阅读&#xff1a;116作者&#xff1a;java_Android前段时间接到领导要求&#xff0c;运营那边会时不时的给我一些.html文件&#xff0c;让我呢把里面的某些东西给解析出来插入到数据库…

慧停车安装后显示服务器异常,智能停车场系统常见故障以及排除方法

原标题&#xff1a;智能停车场系统常见故障以及排除方法随着停车问题日益增多&#xff0c;很多住宅小区都基本安装了智能化的停车场系统&#xff0c;智能停车场系统一般由入口控制机、出口控制机、智能道闸、地感线圈、余位显示屏、图象识别设备、系统软件、管理工作站等组成。…

ios 自定义拍照页面_vivo X27只靠颜值和拍照吃饭?体验过后你也会被系统所折服...

说到vivo X27&#xff0c;相信很多小伙伴都会第一时间想到其帅气的颜值以及强悍的拍照&#xff01;的确&#xff0c;就颜值来说&#xff0c;vivo X27凭借着升降式摄像头、零界全面屏、不凸出的后置三摄以及孔雀纹理的确称的上是2019年的最美旗舰&#xff1b;而拍照就更不用说了…

consul 日志配置_Go语言微服务架构实战:第十一节 启动Consul

启动Consul安装配置好Consul以后&#xff0c;我们可以通过简单的命令启动consul。先来看最简单的启动方式&#xff1a;consul agent -dev在新终端中&#xff0c;执行如上操作。hongweiyulocalhost:~$ consul agent -dev > Starting Consul agent... > Consul agent runni…

chrome修改js数据怎么生效_chrome浏览器中 F12 功能的简单介绍

首先介绍Chrome开发者工具中&#xff0c;调试时使用最多的三个功能页面是&#xff1a;元素&#xff08;ELements&#xff09;、控制台&#xff08;Console&#xff09;、源代码&#xff08;Sources&#xff09;&#xff0c;此外还有网络&#xff08;Network&#xff09;等。元素…

python split函数 空格_Python随笔29:Python基础编程练习题23~24

注&#xff1a;本文所有代码均经过Python 3.7实际运行检验&#xff0c;保证其严谨性。Python编程Python基础练习题23&#xff1a;求三角形斜边上的高输入直角三角形两直角边a、b的值&#xff0c;输出斜边上的高&#xff0c;最后结果使用round(x, 2) 函数四舍五入保留2位小数。输…

docker run后台启动命令_Docker-第五部分:15个 Docker 命令

原文作者&#xff1a;Jeff Hale原文地址&#xff1a;https://towardsdatascience.com/15-docker-commands-you-should-know-970ea5203421翻译&#xff1a;付新圆在这篇文章中&#xff0c;我们将学习15个Dockers CLI命令。如果你还不了解Docker&#xff0c;请查看这个系列的其他…