图片瀑布流实现

实现思路:图片宽度一定,高度不同,下一行的第一张图片放在高度最小的图片的下方,以此类推。

 实现代码:

html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js实现瀑布流效果</title>
    <link href="css/index.css" rel="stylesheet">
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<div id="container">
    <div class="box">
        <div class="pic">
            <img src="images/01.jpg">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/02.jpg">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/03.jpg">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/04.jpg">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/05.jpg">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/06.jpg">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/01.jpg">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/02.jpg">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/03.jpg">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/04.jpg">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/05.jpg">
        </div>
    </div>
    <div class="box">
        <div class="pic">
            <img src="images/06.jpg">
        </div>
    </div>
</div>
<script src="js/index.js"></script>
</body>
</html>

JavaScript代码:

var parent = document.getElementById('container');
function WaterFall() {
    imgLocation('box');
    const data = [{'img':'01.jpg'},{'img':'02.jpg'},{'img':'03.jpg'},
        {'img':'04.jpg'},{'img':'05.jpg'},{'img':'06.jpg'},{'img':'07.jpg'},
        {'img':'08.jpg'},{'img':'09.jpg'},{'img':'10.jpg'},{'img':'11.jpg'},
        {'img':'12.jpg'},{'img':'13.jpg'},{'img':'14.jpg'},{'img':'15.jpg'},
        {'img':'16.jpg'},{'img':'17.jpg'},{'img':'01.jpg'},{'img':'02.jpg'},
        {'img':'03.jpg'},{'img':'04.jpg'},{'img':'05.jpg'},{'img':'06.jpg'},
        {'img':'07.jpg'},{'img':'08.jpg'},{'img':'09.jpg'},{'img':'10.jpg'},
        {'img':'11.jpg'},{'img':'12.jpg'},{'img':'13.jpg'},{'img':'14.jpg'},
    ];
    window.addEventListener('scroll',()=>{
        if (checkLoading('box')){
            //加载新的图片
            data.map((current)=>{
                const newBox = document.createElement('div');
                newBox.className = 'box';
                parent.appendChild(newBox);
                const newPic = document.createElement('div');
                newPic.className = 'pic';
                newBox.appendChild(newPic);
                const newImg = document.createElement('img');
                newImg.src = 'images/'+current.img;
                newPic.appendChild(newImg);
            });
            imgLocation('box');
        }
    });
}


function checkLoading(child){
    const content = getChilds(child);
    const lastTop = content[content.length - 1].offsetTop;
    const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    const pageTop = document.body.clientHeight || document.documentElement.clientHeight;
    if ((scrollTop + pageTop > lastTop) ||(scrollTop == 0 && lastTop < pageTop)){
        return true;
    }
}


function imgLocation(child){
    const content = getChilds(child);
    const imgWidth = content[0].offsetWidth;
    const num = Math.floor(document.body.clientWidth / imgWidth);
    //让图片灵活居中
    parent.style.cssText = 'width:'+ imgWidth * num + 'px;margin:0 auto;';
    //计算图片的高度
    const heightArr = [];
    [].map.call(content,(current,index)=>{
        if (index < num){
            heightArr.push(current.offsetHeight);
        } else {
            //得到图片的最小高度
            const minHeight = Math.min(...heightArr);
            //得到最小高度的序列号
            const minIndex = getMinIndex(minHeight,heightArr);
            current.style.position = 'absolute';
            current.style.top = minHeight + 'px';
            current.style.left = content[minIndex].offsetLeft + 'px';
            //更新最小的高度
            heightArr[minIndex] += current.offsetHeight;
        }
    });
}

//将父级元素下的所有符合条件的子元素获取
function getChilds(child){
    const childArr = [];
    const tagsAll = parent.getElementsByTagName('*');
    [].map.call(tagsAll,(current)=>{
        if (current.className == child){
            childArr.push(current);
        }
    });
    return childArr;
}

function getMinIndex(minHeight,heightArr){
    for (const i in heightArr){
        if (minHeight == heightArr[i]){
            return i;
        }
    }
}

window.addEventListener('load',WaterFall());

结果:运行成功。

编程的时候出现的报错:

报错1:Uncaught TypeError: Cannot read property 'getElementsByTagName' of null

原因:页面的加载顺序问题,将script添加到body的后面

报错2:HTMLCollection []问题

原因:在获取container下的所有节点的时候,const tagsAll = parent.getElementsByTagName('*'); 得到的是HTMLCollection,它不是数组,会动态改变。

所以采用以下编程方法:

[].map.call(tagsAll,(current)=>{
        if (current.className == child){
            childArr.push(current);
        }

待完善的:

窗口大小改变的时候,在不用刷新的情况下图片自动更改适应瀑布流

使用ajax请求图片数据

在点击相应的图片的时候,背景变暗,被点击的图片被放大。

异步请求数据的时候,如果未知图片的高度,怎么办?

移动端的优化。

猜你喜欢

转载自www.cnblogs.com/lanhuo666/p/9998066.html