圖片瀑布流實現

實現思路:圖片寬度必定,高度不一樣,下一行的第一張圖片放在高度最小的圖片的下方,以此類推。css

 實現代碼:html

html代碼:jquery

<!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代碼:ajax

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 app

緣由:頁面的加載順序問題,將script添加到body的後面 異步

報錯2:HTMLCollection []問題 優化

緣由:在獲取container下的全部節點的時候,const tagsAll = parent.getElementsByTagName('*'); 獲得的是HTMLCollection,它不是數組,會動態改變。spa

因此採用如下編程方法:

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

 

待完善的:

窗口大小改變的時候,在不用刷新的狀況下圖片自動更改適應瀑布流

使用ajax請求圖片數據

在點擊相應的圖片的時候,背景變暗,被點擊的圖片被放大。

異步請求數據的時候,若是未知圖片的高度,怎麼辦?

移動端的優化。

相關文章
相關標籤/搜索