1. 程式人生 > >javascript之瀑布流圖片覆蓋

javascript之瀑布流圖片覆蓋

 今天在練習javascript實現瀑布流時遇到了一個看上去非常神奇(實際上無腦)的問題,用js載入十張圖片之後的頁面效果是這樣的:

但是想讓它們按高低順序排列即儘量不留下大量空白空間,於是尋找第一行圖片高度的最小值,然後將下一行的圖片放在高度最小的圖片下面,於是寫了下面的程式段:

var BoxHeightArr = [];
    for(var j=0;j<ccontent.length;j++) {
        if(j<cols)
            BoxHeightArr.push(ccontent[j].offsetHeight);
        else {
            var minHeight = Math.min.apply(null,BoxHeightArr);
            var minIndex = getMinHeightLocation(BoxHeightArr,minHeight);
            ccontent[j].style.position = "absolute";
            ccontent[j].style.top = minHeight+'px';
            ccontent[j].style.left = ccontent[minIndex].offsetLeft+'px';
        }console.log(j);
    }console.log(BoxHeightArr);

但結果卻是這樣的:

發現問題沒有?圖片少了,第二行的圖片只剩下一張,因為後面的幾張圖片設定了絕對定位,並且每次都放在了高度最小的圖片下面,導致之前的圖片被後來的圖片覆蓋掉,以此警醒大家,同時告訴自己,程式碼不要亂寫,不然很可怕的。

那麼解決方法是什麼呢?來看一下:

每次要放置下一行的圖片時,總是找的高度最小的,如果我們放置好第一張圖片之後,將高度最低的那一張圖片的高度值修改為與其下面放置的圖片的高度和,那麼它的高度就不是最小的了,在放置下一張圖片時就會重新尋找高度值最小的那一張圖片,就不會出現覆蓋問題了。

完整程式碼見下方:

html部分:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="css/style.css" type="text/css" rel="stylesheet"/>
    <script src="script/app.js"></script>
</head>
<body>
<div id="container"></div><!--作為容器裝載所有的圖片-->
</body>
</html>

js部分:

window.onload = function() {
    addImages();
    imgLocation('container','box');
};

function addImages() {
    var container = document.getElementById('container');
    for(var j=0;j<5;j++)
        for( var i=1;i<11;i++ ) {
            var divBox = document.createElement('div');
            divBox.setAttribute('class','box');
            var divImg = document.createElement('div');
            divImg.setAttribute('class','box-img');
            var img = document.createElement('img');
            var path = "images/" + i + ".jpg";
            img.setAttribute('src',path);
            divImg.appendChild(img);
            divBox.appendChild(divImg);
            container.appendChild(divBox);
        }
}

// js實現瀑布流佈局實現
function imgLocation(parent,content) {
    var cParent = document.getElementById(parent);
    // 得到所有的box
    var ccontent = getChildElement(cParent,content);
    // offsetWidth得到物體寬度(包括內部width、邊框border和內邊距padding)的數值,
    var imgWidth = ccontent[0].offsetWidth;
    // 一行可以存放圖片的個數
    var cols  = Math.floor(document.documentElement.clientWidth/imgWidth);
    cParent.style.cssText = "width:"+imgWidth*cols+"px;margin:0 auto";
    // 得到所有box即圖片的高度
    var BoxHeightArr = [];
    for(var j=0;j<ccontent.length;j++) {
        if(j<cols) BoxHeightArr.push(ccontent[j].offsetHeight);
        else {
            var minHeight = Math.min.apply(null,BoxHeightArr);
            var minIndex = getMinHeightLocation(BoxHeightArr,minHeight);
            ccontent[j].style.position = "absolute";
            ccontent[j].style.top = minHeight+'px';
            ccontent[j].style.left = ccontent[minIndex].offsetLeft+'px';
            // 使最小值改變,不是最小值
            BoxHeightArr[minIndex] = BoxHeightArr[minIndex]+ccontent[j].offsetHeight;
        }console.log(j);
    }console.log(BoxHeightArr);
}

// 得到高度最小的圖片的索引位置
function getMinHeightLocation(boxHeightArr,minHeight) {
    for(var i=0;i<boxHeightArr.length;i++)
        if( boxHeightArr[i]===minHeight ) return i;
}

// 得到容器中所有的子元素
function getChildElement(parent,content) {
    var contentArr = [];
    var allContent = parent.getElementsByTagName('*');
    for(var i=0;i<allContent.length;i++ )
        if(allContent[i].className===content)
            contentArr.push(allContent[i]);
    return contentArr;
}

效果如下:

這是用js插入的圖片,頁面載入有點慢,不建議使用