zoukankan      html  css  js  c++  java
  • 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代码

     

  • 相关阅读:
    【LeetCode】328. 奇偶链表
    【LeetCode】24. 两两交换链表中的节点
    【LeetCode】83. 删除排序链表中的重复元素
    【LeetCode】141. 环形链表
    【LeetCode】02.07. 链表相交
    【LeetCode】876. 链表的中间结点
    【LeetCode】2. 两数相加
    【LeetCode】02.01. 移除重复节点
    【LeetCode】21. 合并两个有序链表
    【LeetCode】剑指 Offer 06. 从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/bobodeboke/p/5262373.html
Copyright © 2011-2022 走看看