iOS转前端之JS实现瀑布流效果

今天抽空再写一篇,写个瀑布流的效果。做过iOS的都知道瀑布流在iOS中也是个很流行的布局方式,这里就不再多介绍了。我们来看看如何用JS来实现瀑布流的效果。

我就直接上代码了,里面的注释都很清晰。不懂的可以来问我。

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>瀑布流效果</title>
    <link href="css/index.css" rel="stylesheet">
</head>
<body>
    <!--父标签-->
    <div id="main">
        <div class="box">
            <div class="pit">
                <img src="images/0.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/1.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/2.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/3.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/4.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/5.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/6.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/7.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/8.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/9.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/10.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/11.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/12.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/13.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/14.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/15.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/16.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/17.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/18.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/19.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/20.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/21.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/22.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/23.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/24.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/25.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/26.jpg">
            </div>
        </div>
        <div class="box">
            <div class="pit">
                <img src="images/27.jpg">
            </div>
        </div>
    </div>

    <script src="js/index.js" type="text/javascript"></script>
</body>
</html>

CSS:

a, address, b, big, blockquote, body, center, cite, code, dd, del, div, dl, dt, em, fieldset, font, form, h1, h2, h3, h4, h5, h6, html, i, iframe, img, ins, label, legend, li, ol, p, pre, small, span, strong, u, ul, var{
    padding: 0;
    margin: 0;
}

#main {
    position: relative;
}

#main .box {
    padding: 15px 0 0 15px;
    float: left;
}

#main .box .pit {
    padding: 5px;
    border: 1px solid #ddd;
    border-radius: 5px;
    box-shadow: 0 0 2px gray;
    width: 165px;
}

#main .box .pit img {
    width: 165px;
}

JS:

/**
 * Created by huminghao on 2017/7/5.
 */
function $(id) {
    return typeof id === 'string' ? document.getElementById(id) : id;
}

// 当页面加载完毕
window.onload = function () {
    // 实现瀑布流
    waterFlow('main', 'box');

    // 监听页面的滚动
    window.onscroll = function () {
        // 判断是否具备加载图片的条件
        if (checkWillLoadImg()) {
            // 造数据
            var dataImg = {'data' : [{'src' : '0.jpg'}, {'src' : '1.jpg'},{'src' : '2.jpg'},{'src' : '3.jpg'},{'src' : '4.jpg'},{'src' : '5.jpg'},{'src' : '6.jpg'},{'src' : '7.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'},{'src' : '0.jpg'}]}

            for (var i = 0; i < dataImg.data; i ++) {
                // 创建最外层的盒子
                var newBox = document.createElement('div');
                newBox.className = 'box';
                $('main').appendChild(newBox);

                // 创建里面的盒子
                var newPic = document.createElement('div');
                newPic.className = 'pic';
                newBox.appendChild(newPic);

                // 创建图片
                var newImg = document.createElement('img');
                newImg.src = 'images/' + dataImg.data[i].src;
                newPic.appendChild(newImg);
            }
        }
    }

}


// 实现瀑布流
function waterFlow(parent, box) {
    // 让所有盒子的父标签居中
    // 1.拿到所有的盒子
    var allBoxs = $(parent).getElementsByClassName(box);

    // 2.拿到其中一个盒子的宽度
    var boxWidth = allBoxs[0].offsetWidth;

    // 3.求出页面的宽度
    var screenWidth = document.body.clientWidth;

    // 4.求出列数
    var clos = Math.floor(screenWidth / boxWidth);

    // 5.让父标签居中
    $(parent).style.cssText = 'width: ' + clos * boxWidth + 'px; margin: 0 auto';


    // 定位
    // 定义一个高度数组
    var heightArray = [];

    // 遍历
    for (var i = 0; i < allBoxs.length; i ++) {
        // 求出所有盒子的高度
        var boxHeight = allBoxs[i].offsetHeight;

        if (i<clos) { // 第一行
            heightArray.push(boxHeight);

            console.log(heightArray);
        }else { // 剩余行
            // 取出最矮盒子
            var minBoxHeight = Math.min.apply(null, heightArray);
            // 取出最矮盒子对应的索引
            var minBoxIndex = getMinIndex(minBoxHeight, heightArray);
            // 对剩余的盒子进行定位
            allBoxs[i].style.position = 'absolute';
            allBoxs[i].style.top = minBoxHeight + 'px';
            allBoxs[i].style.left = minBoxIndex * boxWidth + 'px';

            // 替换高度
            heightArray[minBoxIndex] = minBoxHeight + boxHeight;
        }
    }
}


// 求出最矮盒子在数组中的索引
function getMinIndex(value, array) {
    for (var i = 0; i < array.length; i ++) {
        if (value == array[i]) {
            return i;
        }
    }
}

// 判断是否具备加载图片的条件
function checkWillLoadImg() {
    // 拿到所有的盒子
    var allBoxs = $('main').getElementsByClassName('box');

    // 取出最后一个盒子
    var lastBox = allBoxs[allBoxs.length - 1];

    // 求出最后一个盒子高度的一半 + 头部偏移的位置
    var lastBoxHeightDis = lastBox.offsetHeight * 0.5 + lastBox.offsetTop;

    // 求出屏幕的高度
    var screenHeight = document.body.clientHeight || document.documentElement.clientHeight;

    // 求出页面偏离浏览器的高度
    var offSetTop = document.body.offsetTop || document.documentElement.offsetTop;
    console.log(lastBoxHeightDis, screenHeight, offSetTop);

    return lastBoxHeightDis < (offSetTop + screenHeight) ? true : false;
}


最后的效果大家可以去我的github下载查看:https://github.com/kiddhmh/HTML-Demo


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值