瀑布流!而且还是响应式的哦!

作者: 高级民工 | 来源:发表于2016-05-21 20:32 被阅读1909次
    Untitled.gif
    没错!这就是瀑布流!是不是很酷炫!看似很难实现,实则很简单!我是用li标签创建这些小块块,当然你也可以根据你的需要在li标签里,插入图片或者其他.下面我们就学习一下,如何实现网页的响应式瀑布流!

    第一步编写HTML

    可能会有小伙伴认为我们有20个块,需要写20个标签,那你就错了,在JS代码中我们可以利用for循环在HTML中查入10个.100个.1000个你想有多少就有多少!当然你最好提前为你的瀑布流做好css样式,我的这些小块都是由li标签创建的,这样在JS中创造的li标签直接赋予相应的类名.

    <!DOCTYPE html>
    <html>
    
        <head>
            <meta charset="UTF-8">
            <title></title>
            <style type="text/css">
                * {
                    margin: 0;
                    padding: 0;
                }
                
                #flow {
                    list-style: none;
                    margin: 0 auto;
                    position: relative;
                }
                
                #flow li {
                    position: absolute;
                    background-color: #CCCCCC;
                    font-size: 50px;
                    width: 200px;
                    transition: all 0.5s;
                }
            </style>
        </head>
    
        <body>
            <ul id="flow">
                <!--<li>1</li>-->
            </ul>
        </body>
    

    第二步 JS代码准备工作

    这步中我们需要创建一个随机数,其函数的返回值我们用来定义每一个li元素的高度,当然如果你不想随机定义高度,那你就去写个数组吧!因为我的整体布局距离左边有10px距离,所以此处创建了一个leftSpace变量接受了一下.细心朋友可能已经发现了我的每一个元素期间都有10px的间距,所以此处创建了一个paddingSpace变量来限定每个li元素的间距.其他的在代码中都有相应的注释,自行理解!

    <script type="text/javascript">
            function ranH (min,max) {
                return parseInt(Math.random()*(max-min+1))+min;
            }
            var flow = document.getElementById("flow");
            // 左边距
            var leftSpace = 10;
            // 间距
            var paddingSpace = 10;
            //高度数组 保存每个li的高度
            var hs = [];
    
    

    第三步 创建li元素

    由于在这步代码中,我们会看到出现bol值,而我们是在第四步定义了bol的值,并且根据bol的值来确定layout函数是实现创建li,还是更新li的位置.在这步我们可以先认为bol为true.首先,是创建li标签,然后获取屏幕的宽度根据屏幕的宽度设置一行有几个li标签,再根据li的标签的个数定义ul的宽度.在定义一下每列的li元素的高度,此处的作用是为了第四步的选出最短列而做准备.在给予每个li标签HTML内容,并且保存每个li的高度.

            //布局函数
            //bol为真时 创建li
            //bol为假时 更新li位置
            function layout (bol) {
                //获取所有的li 用于大小改变时 更新布局
                var lis = document.getElementsByTagName("li");
                var cols = parseInt(document.documentElement.clientWidth/200);  
                //ul宽度 跟随宽度一起变化
                flow.style.width = cols*200 + 10*(cols-1)+20;
                //初始化列高数组
                var arrH =[];
                for (var i = 0; i < cols; i++) {
                    arrH[i]=10;
                }
                function createLi (index) {
                    //获取已有的li或者新建
                    var li = lis[index]||document.createElement("li");
                    li.innerHTML = index;
                    //从数组中获取高度或者随机高度
                    var h = hs[index]||ranH(100,300);
                    li.style.height = h+"px";
                    if (bol) {
                        hs.push(h);
                    }
    

    第四步 插入创建好的带有内容li标签.并且与第三步呼应,实现响应式瀑布流.

    首先求出最短列,将li元素插入最短列下,定义每一个li的位置.在最后利用系统的window.onresize 函数,当屏幕尺寸改变时执行layout()方法中,更新li位置的方法,以实现响应式瀑布流!

    //求最短列
                    var minH = arrH[0];
                    var minI = 0;
                    for (var i = 0; i < cols; i++) {
                        if (minH>arrH[i]) {
                            minH=arrH[i];
                            minI=i;
                        }
                    }
                    //设置left
                    var  l = leftSpace+(200+paddingSpace)*minI;
                    li.style.left = l+"px";
                    //设置top
                    li.style.top = arrH[minI]+"px";
                    //添加
                    bol&&flow.appendChild(li);
    //              alert(li.offsetLeft+"~"+li.offsetTop+"~"+li.offsetWidth+"~"+li.offsetHeight);
                    //更新高度
                    arrH[minI] = arrH[minI] + li.offsetHeight +paddingSpace;
                }
                for (var i =0 ; i < 20 ;i++) {
                    createLi(i);
                }
            }
            //创建
            layout(true);
            window.onresize =function  () {
                //更新
                layout(false);
            }
        </script>
    </html>
    

    相关文章

      网友评论

      • R_JsBest:题主,我看了你的这个对照着写了一份,但是出现一个问题就是容易一直按着其中一列放置,没有在每次添加后正确找到最新布局中最短的那一列,但是加了一句代码之后,就会正常,代码我扔个链接吧,你看一下,是因为我的整体方式跟你有差别导致的,还是你这块确实少写了一句代码。
        https://github.com/ZJH9Rondo/Plug-in/blob/master/lazyload/public/masonry.js

      本文标题:瀑布流!而且还是响应式的哦!

      本文链接:https://www.haomeiwen.com/subject/rdlorttx.html