jQuery实现动态瀑布流布局效果

0x01 前言

今天在tumblr上看到其瀑布流布局,如下图,觉得很有意思便研究了下,发现tumblr使用position:absolute布局的。

照我之前的想法呢,是根据窗口大小,建立N条Col,然后依次将item append到col中。这样成本会小很多,因为只需要写好col的css即可:float:leftdisplay:inline-block

这里写图片描述

0x02 代码编写

HTML,CSS

结构很简单,具体请参考底部的实例。

js

先上全部JS代码

            $(function() {
                var data = Mock.mock({
                    'items|80': [{
                        bgcolor: 'whitesmoke',
                        title: '@title(3,5)',
                        passage: '@paragraph(1,3)',
                        img: '@dataImage(300x220)'
                    }]
                }).items;
                var itemWidth = 320;
                var itemTpl = $('#tpl .falls-item');
                var wrapper = $('.list-container');
                var promiseArr = [];
                var colCount = Math.floor((window.innerWidth - 17) / 320);
                var colTop = []; //每一列最后的高度值
                for (var i = 0; i < colCount; i++) {
                    colTop.push(0);
                }
                console.log(colCount);
                data.forEach(function(val, index) {
                    var item = itemTpl.clone();
                    var colIndex = (index % colCount); //计算出列索引
                    var itemLeft = colIndex * itemWidth; //列数index * 宽度 = left值
                    var itemTop = colTop[colIndex]; //当前列最后的高度值
                    item.find('.title').text(val.title);
                    item.find('.content').text(val.passage);
                    item.find('img').attr('data-src', val.img).attr('data-index', index);
                    item.css({
                        'background-color': val.bgcolor,
                        width: itemWidth,
                    });
                    wrapper.append(item);
                    var dtd = $.Deferred();
                    promiseArr.push(dtd);
                    var prev = new Date().getTime();
                    setTimeout(function() {
                            item.css({
                                left: itemLeft,
                                top: itemTop
                            });
                            console.log(new Date().getTime() - prev);
                            setTimeout(dtd.resolve, 850);
                        }, 300)
                        //插入后更新最后高度值
                    colTop[colIndex] += $(item).height();
                });
                var imgs = $('.list-container img[data-lazy-load]');

                $.when.apply($, promiseArr).done(function() {
                        console.log('animate Done');
                        imgs.scrollFire(150, function(el) {
                            //console.log(el.dataset.index);
                            el.src = el.dataset.src;
                            $(el).addClass('animated fadeIn');
                        });
                        $(window).trigger('scroll');
                    })

我就捡重点讲~

首先我们用MockJS生成随机数据,格式如下:

        var data = Mock.mock({
                    'items|80': [{
                        bgcolor: 'whitesmoke',
                        title: '@title(3,5)',
                        passage: '@paragraph(1,3)',
                        img: '@dataImage(300x220)'
                    }]
                }).items;

生成好数据后,我们做一些初始化准备

var itemWidth = 320;//这里的列宽我们预设为320px,否则不好控制。

var colCount = Math.floor((window.innerWidth - 17) / 320); //计算列数,减去17是减去滚动条的宽度

var promiseArr = []; 为每个动画元素生成promise,在动画执行完毕时,可以通知我们。

接着就是对数组循环遍历,插入HTML。

var colIndex = (index % colCount); //计算出列索引,这里用取余的方式
var itemLeft = colIndex * itemWidth; //列数index * 宽度 = left值
var itemTop = colTop[colIndex]; //当前列最后的高度值,插入HTML后,此值将会更新。

0x03 注意要点

滚动条

当body内容超过window大小,则会出现滚动条,滚动条是占据空间的。

window.innerWidth

$(window).height() == $(body).width()

这里写图片描述
这里写图片描述

$.when

$.when的调用方法是$.when(arg1,arg2),如果直接传入数组,会执行不成功,因此我们用$.when.apply()的方式。

0x04 最终效果

See the Pen xZJdme by chenchen (@larry011) on CodePen.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值