当前位置:网站首页>瀑布流布局
瀑布流布局
2022-07-25 14:59:00 【盖玥希圈外男友(섭소우)】
目录
需求
所谓瀑布流布局,就是含有若干个等宽的列,每一列分别放置图片、视频等,放置的元素都是等宽的,因此可能是不等高的。新的元素到来时,会插入高度较低的那一列,这样形成参差的、视觉上像瀑布一样的布局。
这里简化一下,只要两列等宽布局展示图片即可。
思路
两列布局,直接使用flex布局实现即可。不过,这里不能设置align-items为center,如果设置了将会使图片列居中显示,不符合瀑布流的视觉效果。我设置left和right两列,两列的宽度相等,结构和样式基本就写完了。
然后写JavaScript。其逻辑是,判断当前left和right的高度(我使用clientHeight),如果左边<=右边,则放入左边,否则放入右边。遍历所有的图片,按照这个逻辑放入即可。
代码实现
html部分
<!-- 瀑布流父容器 -->
<div class="container">
<!-- 两列等宽布局 -->
<div class="col left"></div>
<div class="col right"></div>
</div>css部分
.container {
width: 700px;
background-color: aliceblue;
margin: auto;
/* flex布局 */
display: flex;
align-items: flex-start;
}
.col {
flex-basis: 350px;
}
.col img {
/* 固定图片的宽度 */
width: 100%;
}JavaScript部分
// 获取三个元素
let container = document.getElementsByClassName('container')[0]
let left = document.getElementsByClassName('col')[0]
let right = document.getElementsByClassName('col')[1]
// 插入图片
function initImg() {
for (let i = 1; i < 27; i++) {
let img = new Image();
img.src = "./pictures/" + i + ".jpg"
if (left.clientHeight <= right.clientHeight) {
left.appendChild(img)
} else {
right.appendChild(img)
}
}
}
initImg()如代码所示,获取了父元素和左右两列,然后遍历每一张图片,依次判断插入即可。看上去很完美,但是真的如此吗?
实现效果

看上去貌似很完美,也有瀑布的样子。但当拉到页面底部发现:

左边的一大块都是空的,全部放在了右边。这显然不对,因为按照逻辑,左边更短,应该加在左边才对。
问题和修正
问题就在于,img的加载是个异步的过程。再看刚才的for循环:
// 插入图片
function initImg() {
for (let i = 1; i < 27; i++) {
let img = new Image();
img.src = "./pictures/" + i + ".jpg"
if (left.clientHeight <= right.clientHeight) {
left.appendChild(img)
} else {
right.appendChild(img)
}
}
}new了Image对象后,指定了其src,然后立刻判断左右两边的高度。这时,img还没有加载完毕。然而,for循环不会等待它加载完毕。下一张图片产生后,立刻也会判断,但此时上一张图片还没有放到页面上,所以左右的高度很可能就是错误的,从而产生了错误的判断。这就出现了上图中,右列出现了很多很多图片,而左列空白的样子。
解决办法就是,把这个循环写成异步的,只有上一张图片加载完毕后,才去判断下一张图片。
很容易想到,使用Promise完成异步判断。但是对于循环中的Promise,很难清楚地通过then的变化来推进。于是,我决定采用async和await。
这就需要再封装一个方法,这个方法返回Promise,在Promise中加载某一张图片。然后再遍历所有图片,使用async/await,依次调用这个方法,就能得到结果了。
而在Promise中,我们在什么时候调用resolve呢?这就需要监听img的onload事件,设置onload事件的回调函数,在回调函数中调用resolve即可。
经过分析,再次完善代码:
// 加载第index张图片
function loadIndexImg(index) {
return new Promise((resolve, reject) => {
// 当前加载的图片
let img = new Image();
img.src = './pictures/' + index + '.jpg'
img.onload = () => {
if (left.clientHeight <= right.clientHeight) {
left.appendChild(img)
} else {
right.appendChild(img)
}
resolve();
}
})
}
// 插入图片
async function initImg() {
// 要在加载完并插入图片后才去判断下一张,因此采用async/await
for (let i = 1; i <= 26; i++) {
await loadIndexImg(i)
}
}
initImg()可以看到,在initImg中,依次调用loadIndexImg,并且是异步调用。在图片加载完成后再去加载下一张图片,效果应该就可以了。
修正后效果

效果很好!!!
总结
本文实现了简单的两列瀑布流布局,其中需要用到Promise等异步操作。
边栏推荐
- Heyuan City launched fire safety themed milk tea to boost fire prevention and control in summer
- Log4j2 basic configuration
- The solution to the problem that the progress bar of ros2 installation connext RMW is stuck at 13%
- pkg_resources动态加载插件
- Several methods of spark parameter configuration
- awk从入门到入土(20)awk解析命令行参数
- Overview of cloud security technology development
- 39 简洁版小米侧边栏练习
- Melody + realsense d435i configuration and error resolution
- How to use the random number function of JMeter
猜你喜欢

Wechat official account official environment online deployment, third-party public platform access

51 single chip microcomputer learning notes (2)

The concept and operation rules of calculus of variations

"Ask every day" briefly talk about JMM / talk about your understanding of JMM

43 box model

6线SPI传输模式探索

String type time comparison method with error string.compareto

Client error: invalid param endpoint is blank

流程控制(上)

Raft of distributed consistency protocol
随机推荐
Dpkg package download addresses of various platforms (including arm64)
Award winning interaction | 7.19 database upgrade plan practical Summit: industry leaders gather, why do they come?
[thread knowledge points] - spin lock
When using jetty to run items, an error is reported: form too large or form too many keys
As methods for viewing and excluding dependencies
Vs2010添加wap移动窗体模板
河源市区推出消防安全主题奶茶 助推夏季火灾防控
Wechat official account official environment online deployment, third-party public platform access
Live classroom system 05 background management system
Detailed explanation of lio-sam operation process and code
Jmeter的随机数函数怎么用
Resource not found: rgbd_ Launch solution
27 classification of selectors
CMake指定OpenCV版本
Nacos2.1.0 cluster construction
bridge-nf-call-ip6tables is an unknown key异常处理
Several methods of spark parameter configuration
35 快速格式化代码
44 Sina navigation, Xiaomi sidebar exercise
Yarn: the file yarn.ps1 cannot be loaded because running scripts is prohibited on this system.