瀑布流是一种常见的页面布局方式,它会随着内容的不断加载,自动填充页面的空白区域,达到良好的视觉效果和用户体验。下面我来详细介绍一下瀑布流的实现方式(原生JS + jQuery + CSS3)。
HTML 结构
首先要有一个类似于如下的 HTML 结构:
<div class="waterfall">
<div class="item">
<img src="image1.jpg"/>
<div class="description">some text here</div>
</div>
<div class="item">
<img src="image2.jpg"/>
<div class="description">some text here</div>
</div>
...
</div>
其中包含一个父容器 .waterfall
,它的宽度应该为固定值。每个子项 .item
包含一张图片和图片上方一段文字说明的 .description
。正如此处所说, .item
的宽度也应该为固定值。
CSS 样式
再次给出 HTML 结构,我们需要为它添加 CSS 样式。首先,我们需要设置父容器 .waterfall
的样式:
.waterfall {
column-count: 3;
column-gap: 15px;
margin: 15px 0;
width: 1170px;
}
这里提到了 CSS3 的 column-count
,可以将一个元素分割成多个列,同时将子元素列在一起填充每列。column-gap
则是列之间的间距,可以自定义。
接下来就是为 .item
的图片和文字内容设置样式:
.item {
width: 350px;
margin-bottom: 20px;
display: inline-block;
background-color: #fff;
box-sizing: border-box;
border-radius: 6px;
overflow: hidden;
box-shadow: 0 3px 8px rgba(0,0,0,0.16);
-webkit-transition: all .3s ease-out;
transition: all .3s ease-out;
}
.item img {
width: 100%;
display: block;
vertical-align: top;
border-radius: 6px 6px 0 0;
}
.description {
padding: 20px;
font-size: 14px;
color: #666;
text-align: center;
max-height: 80px;
overflow: hidden;
margin-top: -1px;
position: relative;
}
这里的样式包含了一些比较常规的设置,比如给 .item
和 .description
设置了背景色、圆角和阴影等。
JS 实现
有了基本的 HTML 结构和 CSS 样式,接下来就需要使用 JS 实现瀑布流的效果。
首先需要获取 .waterfall
的宽度,然后根据每个 .item
的宽度和间距,计算出实际的列数。比如,我们可以这样实现:
var waterfall = document.querySelector('.waterfall');
var items = document.querySelectorAll('.item');
var waterfallWidth = waterfall.offsetWidth;
var itemWidth = items[0].offsetWidth;
var columnNum = parseInt(waterfallWidth / (itemWidth + 15));
这里使用了 offsetWidth
来获取元素的实际宽度,parseInt()
将计算出的列数转为整数。需要注意的是,间距的值 15
需要与 CSS 样式中的 column-gap
一致。
然后,需要定义一个数组用来存储每一列的高度,初始值都设置为 0:
var columnHeights = new Array(columnNum).fill(0);
接下来就可以开始为每个 .item
设置位置了。由于要达到瀑布流的效果,需要先找到当前列中最短的高度,然后将当前 .item
放在相应的位置上,最后更新当前列的高度。这个操作可以使用以下代码实现:
for (var i = 0; i < items.length; i++) {
var item = items[i];
var itemHeight = item.offsetHeight;
var minHeight = Math.min.apply(null, columnHeights);
var minIndex = columnHeights.indexOf(minHeight);
item.style.left = (itemWidth + 15) * minIndex + 'px';
item.style.top = minHeight + 'px';
columnHeights[minIndex] += itemHeight + 20;
}
其中,offsetHeight
用来获取元素的高度,Math.min.apply(null, columnHeights)
找到了当前列中最短的高度值,indexOf()
找到了这个最短值的索引。
最后,为了让页面能够实现自动加载,需要监听滚动事件,在滚到页面底部时触发加载事件。比如:
window.addEventListener('scroll', function () {
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
var bottomHeight = 100;
var pageHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
if (scrollTop + viewPortHeight >= pageHeight - bottomHeight) {
// 加载新内容
}
});
这里的 scrollTop
、viewPortHeight
、bottomHeight
和 pageHeight
都是计算滚动条位置、窗口高度和页面高度的常用方法。在滚动条滑到底部处时,可以对服务器发出请求,获取新的数据并在页面上渲染。
示例说明
以下是两个示例说明,演示了瀑布流的实现和自动加载的效果。
示例一
一个使用原生 JS 实现瀑布流布局的示例,请参考这里。这个示例使用了前面介绍的方法,通过 JS 计算每一列的高度值,并将后面的图片等元素设置在高度最小的列上。同时,添加了滚动事件监听,当用户滚动到底部时加载新的内容。
示例二
一个使用 jQuery 和无限滚动插件(Infinite Scroll)实现的瀑布流布局的示例,请参考这里。使用无限滚动插件可以实现用户下拉时自动加载新内容的效果,不需要手动监听滚动事件。同时,将操作封装在插件中,大大减少了代码量。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:瀑布流的实现方式(原生js+jquery+css3) - Python技术站