JS实现瀑布流

本文介绍了一种使用JavaScript实现瀑布流布局的方法,包括基本结构搭建、距离控制、图片加载及浏览器宽度适应等关键技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JS实现瀑布流

基本结构

每一张图片,外层是不可见的box,中间是可见的pic装着img,要求盒子宽度固定。

距离控制

要使多个盒子间隙相同时,指定向左浮动并且设定box的上左内边距即可,因为box不可见,实现的效果就类似于pic互相间隔开。

排列规则

先固定第一行,然后按照第一行的宽高,将后续图片插入上一行最短的图片下面。
1. 获取文档宽度和每个盒子宽度(此处取第一个盒子),然后相除获得一行排列盒子的个数,将容器设置为盒子。
2. 定位第一行盒子:top为0,left为单个盒子宽度×盒子顺序的下标,将每一列盒子的高度存储在一个数组中。
3. 获取第一行盒子高度的最小值(Math.min),然后依次比较确定是第几个盒子,对于顺序大于cnum的盒子,即第一行以后,位置即在第一行最短的盒子之下,定位为absolute,top值为最短盒子的高度,left值和上面的最短盒子一样。
4. 然后将盒子高度的数组相应列数的高度值更新,继续排列下一个盒子。

更新图片

当滚动条拉到最后张图片露出一半时,加载剩余的图片。
A 是最后一个 box 盒子的上边距(offsetTop),B 是最后一个盒子高度的一半,C 是用户拉动滚轴的长度(scrollTop),D 是页面高度(clientHeight)。从上图可以看出,当最后的 box 盒子没出到一半时满足
A+B>C+D
而当最后一个盒子出来一半时应该加载剩余图片了,此时A+B<C+D
1. 分别获取A,B,C,D的值,然后比较判断,符合要求时,开始加载数据。
2. 数据储存在json数组中或者从服务器端请求等等,创建一个盒子and里面的图片等等,加入到容器中,然后调用瀑布流的布局函数进行布局。

适应浏览器宽度变化

一行能排列的盒子个数在文档刚加载完成时就固定了。当后续改变宽度时,需要随之进行改变。
在window.onresize时调用waterfall函数。

完整代码(计蒜客):

var dataInit = {
    'data':[
        {'src':'http://res.jisuanke.com/img/upload/20160314/5a2926df15a72b5db4b64a262a3fdca37b67b5c5.jpeg'}
        , {'src':'http://res.jisuanke.com/img/upload/20160314/9dd53e614ca27e4861cdadb28cc28589b7fbd95a.jpeg'}
        , {'src':'http://res.jisuanke.com/img/upload/20160314/b58cda8cbf922faab29e9ce380e5894d84630eae.jpeg'}
        , {'src':'http://res.jisuanke.com/img/upload/20160314/2820b7ccd8cc33cf721cc71173963e7c91da9e68.jpeg'}
        , {'src':'http://res.jisuanke.com/img/upload/20160314/8462d92a3e4229b2a64f486f3f625b4561268823.jpeg'}
        , {'src':'http://res.jisuanke.com/img/upload/20160314/09c69d8f31ca72526211425fd15323ac75fbb9f7.jpeg'}
    ]
};
function waterfall(parent, sclass) {
    var oParent = document.getElementById(parent);
    var aBox = document.getElementsByClassName(sclass);
    var boxwidth = aBox[0].offsetWidth;
    var documentwidth = document.documentElement.clientWidth;
    var cnum = Math.floor(documentwidth/boxwidth);
    oParent.style.width = boxwidth * cnum + 'px';
    var aBoxHeight = new Array();
    for(var i = 0; i < aBox.length; i++) {
        if(i < cnum) {
            aBox[i].style.top = 0 + 'px';
            aBox[i].style.left = boxwidth * i + 'px';
            aBoxHeight.push(aBox[i].offsetHeight);
        }
        else {
            var minHeight = Math.min.apply(null, aBoxHeight);
            var minIndex = getIndex(aBoxHeight, minHeight);
            aBox[i].style.position = 'absolute';
            aBox[i].style.top = minHeight + 'px';
            aBox[i].style.left = aBox[minIndex].offsetLeft + 'px';
            aBoxHeight[minIndex] += aBox[i].offsetHeight;
        }
    }
}
function getIndex(arr, value) {
    for(var i in arr) {
        if(arr[i] == value) return i;
    }
}
window.onload = function() {
    waterfall('main', 'box');
}
function checkScrollside(sClass) {
    var aBox = document.getElementsByClassName(sClass);
    var lastImgIn = aBox[aBox.length-1].offsetTop + Math.floor(aBox[aBox.length-1].offsetHeight/2);
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    var documentHeight = document.documentElement.clientHeight || document.body.clientHeight;
    return (lastImgIn < scrollTop + documentHeight);
}
window.onscroll = function() {
    if(checkScrollside('box')) {
        var oParent = document.getElementById('main');
            for(var i = 0; i < dataInit.data.length; i++) {
            var oBox = document.createElement('div');
            oBox.className = 'box';
            var oPic = document.createElement('div');
            oPic.className = 'pic';
            var oImg = document.createElement('img');
            oImg.src = dataInit.data[i].src;
            oPic.appendChild(oImg);
            oBox.appendChild(oPic);
            oParent.appendChild(oBox);
        }
        waterfall('main', 'box');
    }
}

window.onresize = function() {
    waterfall('main', 'box');
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值