jq实现瀑布流布局

jq实现瀑布流布局

效果图预览
在这里插入图片描述
实现思路:根据网页宽度计算好一排有多少列图片,设置一个空数组记录每一列的高度变化,根据比较每一列的高度大小依次给最短的那一列插入图片

html代码:

<body>
	<div class="waterfall-box"></div>
</body>

css代码:

		*{
            padding: 0;
            margin: 0;
        }
        body,.waterfall-box{
            width: 100%;
            height: 100%;
        }
        .img-item{
            display: flex;
            flex-direction: column;
            border-radius: 8px;
            overflow: hidden;
            position: absolute;
            background: #ffffff;
            box-shadow: 0 0 8px #ccc;
        }
        .img-item,.img-item img{
            width: 290px;
            height: auto;
            display: block;
        }
        .content{
            margin: 0 20px;
            padding: 15px 0;
            border-bottom: 1px solid #eee;
        }
        .user-info{
            padding: 15px 20px;
            display: flex;
            flex-direction: row;
            align-items: center;
        }
        .user-info .userimg img{
            width: 40px;
            height: 40px;
            display: block;
            border-radius: 50%;
        }
        .info{
            margin: 0 0 0 10px;
            display: flex;
            flex-direction: column;
            justify-content: center;
            font-size: 14px;
        }
        .info span:nth-of-type(1){
            color: rgb(197, 120, 20);
        }
        .info span:nth-of-type(2){
            padding: 2px 6px;
            margin: 5px 0 0 0;
            color: rgb(255, 255, 255);
            background: rgb(236, 164, 70);
            border-radius: 20px;
            font-size: 12px;
        }

js代码:

// 瀑布流图片数组
    let img_arr = [
        'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2258625464,2556143219&fm=26&gp=0.jpg',
        'http://image.biaobaiju.com/uploads/20180802/00/1533140278-PKNWsLBzoa.jpg',
        'http://image.biaobaiju.com/uploads/20180802/00/1533140278-JjxDKCWseA.jpg',
        'http://image.biaobaiju.com/uploads/20180802/00/1533140278-oFRMxQtfkd.jpeg',
        'http://image.biaobaiju.com/uploads/20180801/23/1533136201-VtUkzgfLxA.jpg',
        'http://image.biaobaiju.com/uploads/20180801/23/1533136201-wUTXZRcgCp.jpg',
        'http://image.biaobaiju.com/uploads/20181007/15/1538896968-DCWLNoEUJQ.jpg',
        'http://image.biaobaiju.com/uploads/20181007/15/1538896972-fealVIJZhS.jpg',
        'http://image.biaobaiju.com/uploads/20181007/15/1538896972-izKDXVkJOq.jpg',
        'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2258625464,2556143219&fm=26&gp=0.jpg',
        'http://image.biaobaiju.com/uploads/20180802/00/1533140278-PKNWsLBzoa.jpg',
        'http://image.biaobaiju.com/uploads/20180802/00/1533140278-JjxDKCWseA.jpg',
        'http://image.biaobaiju.com/uploads/20180802/00/1533140278-oFRMxQtfkd.jpeg',
        'http://image.biaobaiju.com/uploads/20180801/23/1533136201-VtUkzgfLxA.jpg',
        'http://image.biaobaiju.com/uploads/20180801/23/1533136201-wUTXZRcgCp.jpg',
        'http://image.biaobaiju.com/uploads/20181007/15/1538896968-DCWLNoEUJQ.jpg',
        'http://image.biaobaiju.com/uploads/20181007/15/1538896972-fealVIJZhS.jpg',
        'http://image.biaobaiju.com/uploads/20181007/15/1538896972-izKDXVkJOq.jpg',
        'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2258625464,2556143219&fm=26&gp=0.jpg',
        'http://image.biaobaiju.com/uploads/20180802/00/1533140278-PKNWsLBzoa.jpg'
    ]
    // 上拉加载图片虚拟数据
    let data = [
        'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2258625464,2556143219&fm=26&gp=0.jpg',
        'http://image.biaobaiju.com/uploads/20180802/00/1533140278-PKNWsLBzoa.jpg',
        'http://image.biaobaiju.com/uploads/20180802/00/1533140278-JjxDKCWseA.jpg',
        'http://image.biaobaiju.com/uploads/20180802/00/1533140278-oFRMxQtfkd.jpeg',
        'http://image.biaobaiju.com/uploads/20180801/23/1533136201-VtUkzgfLxA.jpg',
        'http://image.biaobaiju.com/uploads/20180801/23/1533136201-wUTXZRcgCp.jpg',
    ]

    let win_width = $(window).width();                     //获取网页宽度
    let col_num = Math.floor(win_width / 310)              //根据网页宽度计算多少列图片
    let old_col_num = Math.floor(win_width / 310)          //记录列数改变前上一次是多少列图片(此变量用于窗口宽度大小发生改变时)
    let hei_arr = []            //记录每一列图片的总高度
    let resort = true           //网页窗口宽度改变后图片是否在重新排序的状态值
    let loading = true          //上拉加载的状态值
    
    // 重新计算图片列数
    resize();

    $(window).scroll(function(){
        let scroH = $(document).scrollTop(); //滚动条高度
        let viewH = $(window).height();  //可见高度 
        let contentH = $(document).height();  //内容高度
        // 当滚动条距离页面还有150px的时候加载图片
        if(scroH + viewH + 150 >= contentH && loading){
            // 修改加载状态
            loading = false
            // 在这里写ajax数据请求
            // 将获取到的谁数据插入原有的数组
            for(let i = 0;i < data.length; i++){
                img_arr.push(data[i])
            }
            // 将新请求得到的数据排列
            for(let i = 0;i < data.length; i++){
                insertImg((img_arr.length - data.length) + i)
            }
        }
    })

    // 重新计算图片列数
    function resize(){
        $(window).resize(function(){
            win_width = $(window).width();
            old_col_num = Math.floor(win_width / 310) == 0 ? 1 : Math.floor(win_width / 310)
            if(col_num !== old_col_num && resort == true){
                col_num = old_col_num
                resort = false
                // 重新给图片排序
                reSort()
            }
        })
    }

    // 首次加载页面
    for(let i = 0 ; i < img_arr.length; i++ ){
        if(i < col_num){
            let top = 18    //设置图片模板的向上偏移值为18
            let left = i == 0 ? 18 : 290 * i  + 18 * (i + 1)  //以18为基础值设置每个图片容器的向左偏移值
            // 制作图片模板
            module(img_arr[i],top,left,function(html){
                // 返回的模板追加到页面
                $('.waterfall-box').append(html)
                if(i == col_num - 1){
                    // 当第一排图片全部插入完毕后开始计算每一列的高度
                    caluation(col_num)
                }
            })
        }else{
            // 从第二排开始插入图片
            // 设置100毫秒的回调函数,预防图片过大加载过慢而都导致的无法获取图片宽高的问题
            setTimeout(function(){
                // 每次插入图片后给一个30毫秒的延迟
                setTimeout(function(){
                    insertImg(i)
                },30*i)
            },100) 
        }
    }

    // 第一行图片排列完成后计算每一列的高度
    function caluation(num){
        let arr = []
        for(let i = 0 ;i < num; i++){
            // 获取到每一个图片模板的高度,给山下两图片模板增加18px的间距
            let div_height = $('.img-item').eq(i).height() + 18
            arr.push(div_height)
            // 把第一排每一列的高度写进事先设置好的空数组
            hei_arr = arr
        }
    }

    // 插入图片
    function insertImg(idx){
        // 获取最小的高度值
        let min_height = Math.min.apply(null, hei_arr)
        // 获取最大的高度值
        let max_height = Math.max.apply(null, hei_arr)
        // 获取最小高度在数组里的下标
        let min_index = hei_arr.indexOf(min_height)
        let top = min_height + 18
        let left = min_index == 0 ? 18 : 290 * min_index  + 18 * (min_index + 1)
        module(img_arr[idx],top,left,function(html){
            $('.waterfall-box').append(html)
            let div_height = $('.img-item').eq(idx).height() + 18
            hei_arr[min_index] = hei_arr[min_index] + div_height
            if(idx == img_arr.length - 1){
                // 遍历到最后一张图片的时候
                // 图片可进行重新排列
                resort = true
                // 修改状态可在此加载数据
                loading = true
            }
        })
    }

    // 图片重新排序
    function reSort(){
        for(let i = 0; i < img_arr.length; i++){
            if(i < col_num){
                let top = 18
                let left = i == 0 ? 18 : 290 * i  + 18 * (i + 1)
                $('.img-item').eq(i).animate({"top": top + 'px',"left": left + 'px'},200,function(){})
                if(i == col_num - 1){
                    caluation(col_num)
                }
            }else{
                setTimeout(function(){
                    let min_height = Math.min.apply(null, hei_arr)
                    let max_height = Math.max.apply(null, hei_arr)
                    let min_index = hei_arr.indexOf(min_height)
                    let top = min_height + 18
                    let left = min_index == 0 ? 18 : 290 * min_index  + 18 * (min_index + 1)
                    let div_height = $('.img-item').eq(i).height() + 18
                    hei_arr[min_index] = hei_arr[min_index] + div_height
                    $('.img-item').eq(i).animate({"top": top + 'px',"left": left + 'px'},200,function(){
                        if(i == img_arr.length - 1){
                            resort = true 
                        }
                    })
                },80)
            }
        }
    }

    // 图片模板
    function module(img,top,left,fun){
        // img:图片链接
        // top:模板到页面顶端的偏移值
        // left:模板到页面顶端的偏移值
        // fun:回调函数
        let html = `
            <div class="img-item" style="top:` + top + `px;left:` + left + `px">
                <img src="`+ img +`">
                <div class="content">
                    这是一个瀑布流的例子
                    这是一个瀑布流的例子
                    这是一个瀑布流的例子
                </div>
                <div class="user-info">
                    <div class="userimg">
                        <img src="http://pic.qqtn.com/up/2017-11/2017112717262155194.png">
                    </div>
                    <div class="info">
                        <span>白纸一张</span>
                        <span>白纸一张的博客</span>
                    </div>
                </div>
            </div>
        `
        fun(html)
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值