实现瀑布流的几种方式

概念:瀑布流,又称瀑布流式布局,是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部

 特点:

  1.     琳琅满目:整版以图片为主,大小不一的图片按照一定规律排列
  2.     唯美:图片的风格以唯美的图片为主
  3.     操作简单:在浏览网站时只需轻轻滑动一下鼠标滚轮,一切的秒图片便可呈现在眼前

布局优点:

  •     有效的降低了界面的复杂度,节省了空间
  •     对触屏设备来说,交互方式更符合直觉
  •     更高的参与度

瀑布流1

<body>

    <div id="water"></div>

    <script src="./js/waterfall.js"></script>

    <script>
        //得到元素
        var div = document.getElementById("water");

        //图片数组
        var imgs = [];

        //循环,将图片加载出来
        for (var i = 0; i <= 40; i++) {
            imgs.push("img/" + i + ".jpg");
        }

        // 调用函数
        creatWaterFall(div, imgs, 220);
    </script>
</body>
#water {
  position: relative;
  width: 90%;
  margin: 0 auto;
  /* outline: 1px solid; */
}


#water img {
  box-shadow: 0 0 10px rgba(0, 0, 0, .5);
  border-radius: 10px;
  transition: all .5s;
}
/**
 * [creatWaterFall description]
 * @param  {[type]} areaDom    [容器]
 * @param  {[type]} urls       [图片的url地址数组]
 * @param  {[type]} everyWidth [每张图片的宽度]
 * @return {[type]}            [description]
 */
function creatWaterFall(areaDom,urls,everyWidth){
    //有多少列
    var colNumber;

    //每张图片之间的间隙
    var gap;

    // 1.创建图片
    creatImgDoms();

    //2.设置图片的坐标
    setImgPosition();

    //窗口改变事件  函数防抖
    var timer = null;
    window.onresize = function() {

      if(timer){
        clearTimeout(timer);
      }

      timer = setTimeout(function(){
          setImgPosition();
      },500);
    };


  //函数区

  /**
   * 计算
   *
   */
  function cal(){

    //得到容器的宽度
    var containerWidth = parseInt(areaDom.clientWidth);

    //列数
    colNumber = parseInt(containerWidth / everyWidth);

    //剩余空间
    var space = containerWidth-colNumber*everyWidth;

    //每张图片之间的间距
    gap = space / (colNumber + 1);
  }

  /**
   *
   * @return {[type]} [创建函数的dom对象]
   */
    function creatImgDoms(){
      for(var i=0; i<urls.length; i++){

        //每张图片的地址数组
        var url = urls[i];

        //创建一个img对象,并设置相关样式
        var img = document.createElement("img");
        img.src = url;
        img.style.width = everyWidth + "px";
        img.style.position = "absolute";
        img.onload = function(){
          setImgPosition();
        };

        //将图片放到容器里
        areaDom.appendChild(img);
      }
    }

    /**
     * 设置每张图片的坐标
     */
    function setImgPosition(){
      cal();

      //存放的是每一列下一个图片的纵坐标
      var colY = new Array(colNumber);

      colY.fill(0);//将数组的每一项填充为0

      for(var i = 0; i < areaDom.children.length; i++){

        //得到图片路径
          var img = areaDom.children[i];

          //找到数组colY中的最小值
          var y = Math.min(...colY); // y坐标

          var index = colY.indexOf(y); // 第几列
          var x = (index + 1) * gap + index * everyWidth;
          img.style.left = x + "px";
          img.style.top = y + "px";

          //更新数组
          colY[index] += parseInt(img.height) + gap;
          // console.log(img.height);
      }

      // 找到数组中最大的数字
      var height = Math.max(...colY);
      areaDom.style.height = height + "px";
    }
}

 

瀑布流2--无限瀑布流

 <div class="out"></div>
.out {
    margin: 0 auto;
    width: 90%;
    position: relative;
}

.in {
    float: left;
}

img {
    margin: 10px;
    padding: 10px;
    /* border: 1px solid #000; */
    border-radius: 10px;
    box-shadow: 0 0 10px rgba(0, 0, 0, .5);
}
  // 模拟后台数据
        var dataStr =
            '{"src":["i1.jpg","i2.jpg","i3.jpg","i4.jpg","i5.jpg","i6.jpg","i7.jpg","i8.jpg","i9.jpg","i10.jpg","i11.jpg","i12.jpg","i13.jpg","i14.jpg","i15.jpg"]}';

        //将json数据解析成js
        var dataObj = JSON.parse(dataStr);

        //得到元素
        var outDiv = document.querySelector('.out');

        // 添加图片
        function addDiv_inOut() {
            //循环 将图片添加到页面中
            for (var i = 0; i < dataObj.src.length; i++) {
                var div = document.createElement('div');
                div.className = 'in';
                div.innerHTML = '<img src="img/' + dataObj.src[i] + '"/>';
                outDiv.appendChild(div);
            }
        }

        //构建瀑布
        function createWaterFall() {
            //求出一行能放多少张图片

            //拿到所有的小div
            var inDivs = document.querySelectorAll('.in');

            //得到视口的宽度  考虑浏览器兼容性问题
            // var viewportWidth = document.documentElement.clientWidth || document.body.clientWidth;
            var viewportWidth = parseInt(document.documentElement.clientWidth || document.body.clientWidth);

            //拿到图片的宽度
            var oneWidth = inDivs[0].offsetWidth;

            //拿到视口中一行所能放的图片的个数
            var num = Math.floor(viewportWidth / oneWidth);

            //得到最外层div的宽度
            outDiv.style.width = num * oneWidth + "px";

            // 用来保存图片的高度
            var heightArr = [];

            //对每一张图片设置定位,构建瀑布流
            for (var j = 0; j < inDivs.length; j++) {

                if (j < num) {
                    //如果是第一行图片则不需要设置定位 但是需要保存高度
                    heightArr.push(inDivs[j].offsetHeight);
                } else {
                    //如果不是第一行图片,则需要设置定位。根据第一行设置定位
                    inDivs[j].style.position = 'absolute';

                    //在高度数组中找到最小高度【当做这张图片的top定位值】
                    var minHeight = Math.min.apply(null, heightArr);

                    //在高度数组中,找到最小高度的下标
                    var minIndex = heightArr.indexOf(minHeight);

                    //根据找到的下标,然后找到这个最小的div,并获取它的左定位[定位的left值]
                    var tempLeft = inDivs[minIndex].offsetLeft;

                    //设置图片的定位
                    inDivs[j].style.top = minHeight + 'px';
                    inDivs[j].style.left = tempLeft + 'px';

                    //将高度数组中最小的高度累加到当前图片的高度上
                    heightArr[minIndex] = heightArr[minIndex] + inDivs[j].offsetHeight;
                }
            }
        }

        addDiv_inOut();

        //当页面加载完毕后在执行其他操作
        window.onload = function() {
            createWaterFall();
        }

        //计算滚动距离
        function judgeMethod() {
            var inDivs = document.querySelectorAll('.in');

            // 页面滚动的距离
            var scrollHeight = document.documentElement.scrollTop || document.body.scrollTop;

            //屏幕的距离
            var screenClient = document.documentElement.clientHeight;

            //最后一个元素的高度
            var lastDivHeight = inDivs[inDivs.length - 1].offsetTop;

            if (scrollHeight + screenClient > lastDivHeight) {
                return true;
            }
        }

        //滚动事件   实现无限瀑布流
        window.onscroll = function() {
            if (judgeMethod()) {
                addDiv_inOut();
                createWaterFall();
            }
        }

 

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白小白从不日白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值