瀑布流布局是一种比较流行的页面布局方式,表现为参差不齐的多栏卡片。跟网格布局相比,显得更灵动,更具艺术气息。
创新互联公司从2013年开始,是专业互联网技术服务公司,拥有项目成都网站设计、成都做网站网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元如东做网站,已为上家服务,为如东各地企业和个人服务,联系电话:13518219792
瀑布流布局
实现瀑布流布局的方式有多种,比如multi-column布局,grid布局,flex 布局等。但是这些实现方式都有各自的局限性,代码也略复杂。
其实,有个最原始、最简单,也是兼容性最好的实现方式,那就是使用绝对定位。瀑布流布局的元素是一些等宽不等高的卡片,只要根据元素的实际宽高计算出自己的坐标位置就行了。
要计算坐标自然要用到 JavaScript,这就不是纯 CSS 方案,对某些前端极客来讲显得不那么纯粹。不过只要理清思路了,也用不了几行代码。本文就给出最近实现的一个版本。
- // 计算每个卡片的坐标
- export function calcPositions({ columns = 2, gap = 7, elements }) {
- if (!elements || !elements.length) {
- return [];
- }
- const y = []; //上一行卡片的底部纵坐标数组,用于找到新卡片填充位置
- const positions = []; // 每个卡片的坐标数组
- elements.forEach((item, index) => {
- if (y.length < columns) { // 还未填满一行
- y.push(item.offsetHeight);
- positions.push({
- left: (index % columns) * (item.offsetWidth + gap),
- top: 0
- });
- } else {
- const min = Math.min(...y); // 最小纵坐标
- const idx = y.indexOf(min); // 纵坐标最小的卡片索引
- y.splice(idx, 1, min + gap + item.offsetHeight); // 替换成新卡片的纵坐标
- positions.push({
- left: idx * (item.offsetWidth + gap),
- top: min + gap
- });
- }
- });
- // 由于采用绝对定位,容器是无法自动撑开的。因此需要计算实际高度,即最后一个卡片的top加上自身高度
- return { positions, containerHeight: positions[positions.length - 1].top + elements[elements.length - 1].offsetHeight };
- }
上面这段代码的作用就是计算每个卡片的left、top,以及容器的总高度。关键位置都有注释,应该不难理解。
有了这几行核心代码,要想封装成瀑布流组件就很容易了。以 Vue 为例,可以这样封装:
MasonryLite.vue
使用组件:
{{ item.title }}
不过这样其实还会有点问题,就是doLayout的执行时机。因为该方案基于绝对定位,需要元素在渲染完成后才能获取到实际宽高。如果卡片内有延迟加载的图片或者其他动态内容,高度会发生变化。这种情况下就需要在DOM更新后主动调用一次doLayout重新计算布局。
如果大家有更好的实现方案,欢迎交流!
代码仓库:https://github.com/kaysonli/masonry-lite
npm 包:masonry-lite
如果觉得对你有帮助,帮忙点个不要钱的star。
本文转载自微信公众号「1024译站」,可以通过以下二维码关注。转载本文请联系1024译站公众号。
标题名称:实现瀑布流布局,就这几行代码?
URL链接:http://www.shufengxianlan.com/qtweb/news44/406094.html
成都网站建设公司_创新互联,为您提供手机网站建设、定制开发、服务器托管、标签优化、响应式网站、软件开发
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联