javascript实例学习之五——瀑布流布局

瀑布流布局的特征:

1,各列的高度参差不齐

2,页面向下滚动时,自动请求和加载新数据

目前,瀑布流布局的主流实现方式有两种:

1,基于浮动,每一列是一个ul,这些ul都向左浮动,这种方法的好处是布局容易,加载较为复杂;

2,基于绝对定位,只有一个ul,所有item都加入该ul中,ul相对定位,item绝对定位,所有图片的宽度已知,所有图片的高度信息使用一个数组记录所有图片的高度(即offsetHeight信息)。

一、基于浮动的瀑布流布局

基于浮动瀑布流布局的html页面

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>瀑布流布局</title>
</head>
<style>
    *{margin:0;padding:0;}
    ul>li{list-style: none}
    #div1{750px;margin:20px auto;overflow: hidden;}
    ul{237px;margin:5px;float:left;}
</style>
<body>
    <div id="div1">
        <ul>
            <li>
                <img src="./images/feed/1.jpg" alt="">
                <p>1111111111</p>
            </li>
            <li>
                <img src="./images/feed/2.jpg" alt="">
                <p>1111111111</p>
            </li>
            <li>
                <img src="./images/feed/2.jpg" alt="">
                <p>1111111111</p>
            </li>
        </ul>
        <ul>
            <li>
                <img src="./images/feed/2.jpg" alt="">
                <p>22222222222</p>
            </li>
            <li>
                <img src="./images/feed/3.jpg" alt="">
                <p>22222222222</p>
            </li>
            <li>
                <img src="./images/feed/3.jpg" alt="">
                <p>22222222222</p>
            </li>
        </ul>
        <ul>
            <li>
                <img src="./images/feed/3.jpg" alt="">
                <p>3333333333</p>
            </li>
            <li>
                <img src="./images/feed/1.jpg" alt="">
                <p>3333333333</p>
            </li>
            <li>
                <img src="./images/feed/1.jpg" alt="">
                <p>3333333333</p>
            </li>
        </ul>        
    </div>
    <script src="./js/jquery-2.1.4.min.js"></script>
    <script src="./js/feed.js"></script>
</body>

</html>
基于浮动的瀑布流布局html代码

基于浮动瀑布流布局的js代码

//获取元素相对于屏幕的距离
function getTop(obj) {
    var top = 0;
    while (obj) {
        top += obj.offsetTop;
        obj = obj.offsetParent;
    }
    return top;
}

document.addEventListener('DOMContentLoaded', function() {
    var aUls = document.getElementsByTagName('ul');
    var flag = true;
    //添加数据
    function addNext(uls, jsonObj) {
        if (jsonObj['code']) {
            //说明jsonObj['code']等于0,数据发送完毕,没有更新的数据
            flag = true;
        }
        console.log(flag);
        var realData = jsonObj['list'];
        for (var i = 0; i < realData.length; i++) {
            var curData = realData[i];
            for (var j = 0; j < curData['src'].length; j++) {
                var oLi = document.createElement('li');
                oLi.innerHTML = '<img src="' + curData['src'][j] + '"><p>' + curData['title'][j] + '</p>';
                uls[i].appendChild(oLi);

            }
        }
    }
    window.addEventListener('scroll', function() {
        //可视区域(视口)的高度

        var viewHeight = document.documentElement.clientHeight;
        //滚动条滚动的高度(隐藏在上方的高度)
        var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
        for (var i = 0; i < aUls.length; i++) {
            var aLi = aUls[i].getElementsByTagName('li');
            var lastLi = aLi[aLi.length - 1];
            //判断最后一个是否进入可视区
            if (getTop(lastLi) < viewHeight + scrollY && flag) {
                //将flag置为false,否则有几个ul,就会连续触发几次
                flag = false;
                //发送ajax请求
                //理论上应当发送ajax请求,这里省略,直接赋予数值 
                // $.ajax({
                // });
                var data = {
                    code: 0,
                    list: [{
                        src: ['./images/feed/3.jpg', './images/feed/2.jpg', './images/feed/2.jpg'],
                        title: ['222222222222', '222222222222', '222222222222']
                    }, {
                        src: ['./images/feed/1.jpg', './images/feed/2.jpg', './images/feed/3.jpg'],
                        title: ['333333333333', '333333333333', '333333333333']
                    }, {
                        src: ['./images/feed/2.jpg', './images/feed/1.jpg', './images/feed/1.jpg'],
                        title: ['111111111111', '111111111111', '111111111111']
                    }]
                };
                addNext(aUls, data);
            }
        }
    }, false);
}, false);
基于浮动的瀑布流布局js代码

核心思想

监听window的scroll函数,将最后一个列表项的top值和(滚动隐藏高度+视口高度)相比较,判断加载时机

二、基于决定定位的瀑布流布局

基于浮动瀑布流布局的html页面

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>基于绝对定位的瀑布流布局</title>
    <style>
    * {
        margin: 0;
        padding: 0;
    }
    ul>li {
        list-style: none;
    }
    .div1 {
        margin: 20px auto;
         730px;
        position: relative;
    }
    li{
        position:absolute;
    }
    </style>
</head>

<body>
    <div class="div1">
        <ul>
            <li>
                <img src="./images/feed/1.jpg" alt="">
                <p>11111111111</p>
            </li>
            <li>
                <img src="./images/feed/3.jpg" alt="">
                <p>11111111111</p>
            </li>
            <li>
                <img src="./images/feed/2.jpg" alt="">
                <p>11111111111</p>
            </li>
            <li>
                <img src="./images/feed/2.jpg" alt="">
                <p>11111111111</p>
            </li>
            <li>
                <img src="./images/feed/1.jpg" alt="">
                <p>11111111111</p>
            </li>
            <li>
                <img src="./images/feed/1.jpg" alt="">
                <p>11111111111</p>
            </li>
            <li>
                <img src="./images/feed/3.jpg" alt="">
                <p>11111111111</p>
            </li>
            <li>
                <img src="./images/feed/1.jpg" alt="">
                <p>11111111111</p>
            </li>
            <li>
                <img src="./images/feed/2.jpg" alt="">
                <p>11111111111</p>
            </li>
        </ul>
    </div>
    <script src="./js/jquery-2.1.4.min.js"></script>
    <script src="./js/jquery-2.1.4.min.js"></script>
    <script src="./js/feed2.js"></script>
</body>

</html>
基于绝对行为的瀑布流布局

基于浮动瀑布流布局的js代码

//获取元素相对于屏幕的距离
function getTop(obj) {
    var top = 0;
    while (obj) {
        top += obj.offsetTop;
        obj = obj.offsetParent;
    }
    return top;
}
var aHeight = {
    L: [],
    C: [],
    R: []
};

function refreshUl(aLis) {
    for (var i = 0; i < aLis.length; i++) {
        var tmp = i % 3;
        switch (tmp) {
            case 0:
                aLis[i].style.left = "5px";
                aHeight['L'].push(aLis[i].offsetHeight);
                var step = Math.floor(i / 3);
                var curHeight = 0;
                for (var k = 0; k < step; k++) {
                    curHeight += aHeight['L'][k] + 5;
                }
                aLis[i].style.top = curHeight + 'px';
                break;
            case 1:
                aLis[i].style.left = "247px";
                aHeight['C'].push(aLis[i].offsetHeight);
                var step = Math.floor(i / 3);
                var curHeight = 0;
                for (var k = 0; k < step; k++) {
                    curHeight += aHeight['C'][k] + 5;
                }
                aLis[i].style.top = curHeight + 'px';
                break;
            case 2:
                aLis[i].style.left = "489px";
                aHeight['R'].push(aLis[i].offsetHeight);
                var step = Math.floor(i / 3);
                var curHeight = 0;
                for (var k = 0; k < step; k++) {
                    curHeight += aHeight['R'][k] + 5;
                }
                aLis[i].style.top = curHeight + 'px';
                break;
        }
    }
}
$(function() {
    var oUl = document.getElementsByTagName('ul')[0];
    var aLis = oUl.getElementsByTagName('li');
    //使用数组记录每个元素的高度
    console.log('li个数:'+aLis.length);
    var flag = true;
    refreshUl(aLis);

    //下滑加载部分的代码
    window.addEventListener('scroll', function() {
        var aLis = oUl.getElementsByTagName('li');
        var lastLi = aLis[aLis.length - 1];
        var viewHeight = document.documentElement.clientHeight || document.body.clientHeight;
        var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
        if (getTop(lastLi) < viewHeight + scrollY &&flag) {
            var data = {
                'code': 0,
                'liData': {
                    'src': ['./images/feed/1.jpg', './images/feed/1.jpg', './images/feed/1.jpg'],
                    'title': ['5555555555', '5555555555', '5555555555']
                }
            }

            if (data['code'] == 0) {
                //说明已经没有更多数据
                flag = false;
            }
            var srcData = data['liData']['src'];
            var titleData = data['liData']['title'];
            for (var i = 0; i < srcData.length; i++) {
                var curLi = document.createElement('li');
                curLi.innerHTML = '<img src="' + srcData[i] + '"><p>' + titleData[i] + '</p>';
                oUl.appendChild(curLi);
            }
            aLis = oUl.getElementsByTagName('li');
            console.log('aLis个数2:'+aLis.length);
            refreshUl(aLis);
        }
    }, false);

});
基于绝对定位的瀑布流的js代码

 

原文地址:https://www.cnblogs.com/bobodeboke/p/5262373.html