1. 什么是瀑布流布局
瀑布流布局,顾名思义,就像是一道瀑布,瀑布上的水流会从不同的高度流下,而在页面中,不同的内容会从不同的列或行进行排布。瀑布流布局最早是由 Pinterest 推崇,随后被 Instagram、堆糖等社交网站所采用,成为了时下比较流行的一种网页展示方式。
那么在 CSS 中,如何通过代码实现瀑布流布局呢?本文将从布局方案、响应式、优化等方面进行讲解。
2. 布局方案
2.1 实现原理
瀑布流布局的实现原理基于多列布局。比如我们要实现两列布局,我们可以使用 float
属性来使两个元素排在不同的位置。但在瀑布流布局中,我们很难事先知道每一个元素的宽度和高度,因此我们需要使用 JavaScript 来计算,找到当前剩余高度最小的列,然后将元素添加到该列中。这样就可以进行瀑布流式的布局了。
2.2 实现代码
下面是一个简单的实现瀑布流布局的代码示例。其中 getMinIndex()
函数是用来找到当前剩余高度最小的列,waterfall()
函数中主要是调用了该函数,然后将元素逐个添加到列中。
function getMinIndex(arr, min) {
for (var i in arr) {
if (arr[i] === min) {
return i;
}
}
}
function waterfall(parent, box) {
var oParent = document.getElementById(parent);
var oBoxs = oParent.getElementsByClassName(box);
var oBoxW = oBoxs[0].offsetWidth;
var cols = Math.floor(document.documentElement.clientWidth/oBoxW);
oParent.style.cssText = 'width:'+oBoxW*cols+'px;margin:0 auto;';
var hArr = [];
for (var i = 0; i < oBoxs.length; i++) {
if (i < cols) {
hArr.push(oBoxs[i].offsetHeight);
} else {
var hMin = Math.min.apply(null, hArr);
var index = getMinIndex(hArr, hMin);
oBoxs[i].style.position = 'absolute';
oBoxs[i].style.top = hMin + 'px';
oBoxs[i].style.left = oBoxW * index + 'px';
hArr[index] += oBoxs[i].offsetHeight;
}
}
}
3. 响应式设计
3.1 实现原理
在移动设备的普及下,响应式设计逐渐成为了重要的设计趋势。瀑布流布局的响应式设计可以通过使用 CSS3 中的 @media
规则和 JavaScript 来实现。
3.2 实现代码
下面是一个实现瀑布流响应式设计的代码示例。其中 setCols()
函数是用来设置初始列数,resize()
函数则是在窗口大小发生变化时调用的函数,用来判断当前的列数和浏览器宽度是否匹配,若不匹配,则重新进行布局。
function setCols() {
var w = document.documentElement.clientWidth;
if (w > 1200) {
return 5;
} else if (w > 992) {
return 4;
} else if (w > 768) {
return 3;
} else if (w > 480) {
return 2;
} else {
return 1;
}
}
function resize(parent, box) {
var cols = setCols();
var oParent = document.getElementById(parent);
oParent.style.cssText = 'width:1000px;margin:0 auto;';
var oBoxs = oParent.getElementsByClassName(box);
var oBoxW = oBoxs[0].offsetWidth;
var w = oBoxW * cols + 'px';
oParent.style.width = w;
var hArr = [];
for (var i = 0; i < oBoxs.length; i++) {
if (i < cols) {
hArr.push(oBoxs[i].offsetHeight);
} else {
var hMin = Math.min.apply(null, hArr);
var index = getMinIndex(hArr, hMin);
oBoxs[i].style.position = 'absolute';
oBoxs[i].style.top = hMin + 'px';
oBoxs[i].style.left = oBoxW * index + 'px';
hArr[index] += oBoxs[i].offsetHeight;
}
}
}
window.onload = function() {
resize('parent', 'box');
};
window.onresize = function() {
resize('parent', 'box');
};
4. 优化
4.1 图片加载
在瀑布流布局中,由于每一张图片的高度和宽度都不确定,因此在图片加载时必须先读取图片的宽度和高度等信息,然后再计算元素的位置。为了避免因为图片未加载而导致的布局错误,可以预先设置图片的宽度和高度等信息。
<img src="img.jpg" width="300" height="200">
同时,还可以使用 JavaScript 来预加载图片,避免页面出现空白。
var image = new Image();
image.onload = function() {
// 当图片加载完成后,将其添加到页面中
};
image.src = "img.jpg";
4.2 懒加载
在使用瀑布流布局时,往往会有大量的图片,如果一次性加载所有的图片,会导致页面的加载速度变慢。因此,我们可以使用懒加载的方式来实现。
懒加载的原理是,当页面加载时,只加载可视区域内的图片,当用户滚动页面时,再加载其他位置的图片。这样可以避免一次性加载所有图片对页面性能的影响。
4.3 缓存
由于瀑布流布局的元素位置是通过 JavaScript 计算得出的,因此每次页面刷新都需要重新计算元素位置,这会对页面的性能造成影响。为了避免这个问题,我们可以使用浏览器缓存,将每一列的高度保存在 cookie 中,下次打开页面时直接从缓存中读取。
5. 总结
本文从布局方案、响应式设计、优化等方面详细讲解了如何实现瀑布流布局,并提供了相关的代码示例。通过本文的学习,相信读者对于如何实现瀑布流布局已经有了一定的认识。