如何用JS实现网页瀑布流布局


Posted in Javascript onApril 24, 2021

前言:

瀑布流 又称瀑布流式布局,是比较流行的一种网站页面布局方式。即多行等宽元素排列,后面的元素依次添加到其后,等宽不等高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置。

什么是瀑布流布局:

先看效果:

如何用JS实现网页瀑布流布局

  • 图片多行等宽元素排列,后面的元素依次添加到其后,等宽不等高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置。
  • 为了方便理解,在此先给上html、css代码

不完整html代码:

<div id="container">
        <div class="box">
            <div class="box-img">
                <img src="./img/1.jpg" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/2.jpg" alt="">
            </div>
        </div>
        <div class="box">
            <div class="box-img">
                <img src="./img/3.jpg" alt="">
            </div>
        </div>
     </div>
     ......<!-- 省略了图片,多少张图片自行决定-->

完整的css代码

*{
        padding: 0;
        margin: 0;
    }
    #container{
        position: relative;
    }
    .box{
        float: left;
        padding: 15px;
    }
    .box-img {
        width: 150px;
        padding: 5px;
        border: 1px solid #ccc ;
        box-shadow: 0 0 5px #ccc;
        border-radius: 5px;
    }
    .box-img img{
        width: 100%;
        height: auto;
    }

如何实现:

简单地来说,如果要实现瀑布流布局,得完成这几件事✍

1. 获取图片

function getChildElemnt() {
    const contentArr = []//定义数组准备装图
    const parent = document.getElementById(container)//得到整个页面
    const allContent = parent.getElementsByTagName('*')//得到整个标签
    console.log(allContent);
    for (var i = 0; i < allContent.length; i++) {
      if (allContent[i].className == 'box') {
        contentArr.push(allContent[i])//将class='box'的标签装入数组
      }
    }
    console.log(contentArr);
    return contentArr//返回数组
 }

2. 设置图片宽带

var ccontent = getChildElemnt()
  var imgWidth = ccontent[0].offsetWidth//令所有图片宽度等于第一张图片

3. 计算浏览器页面一行最多能存放图片的数量

var dWidth=document.documentElement.clientWidth//页面宽度
var num = Math.floor(dWidth/ imgWidth)
//Math.floor()向下取整

4. 比较图片高度

因为在瀑布流布局中,当第一行图片已经摆满后,第二行的第一张图片要放在第一行中高度最小的图片的下面

var BoxHeightArr = []//定义一个数组,把每张图片的高度依次放进去
    for (var i = 0; i < ccontent.length; i++) {
      if (i < num) {
        BoxHeightArr[i] = ccontent[i].offsetHeight//将图片的高度存入数组
      } else {//当第一行已经存放不了图片后
        var minHeight = Math.min.apply(null, BoxHeightArr)//比较出上一行最小的高度
        
      }
    }

5. 得到上一行中最小高度图片的位置

//定义一个getMinHeightLocation函数,给它传入BoxHeightArr上一行全部图片,和minHeight上一行图片的最小高度
  function getMinHeightLocation(BoxHeightArr, minHeight) {
    for (var i in BoxHeightArr) {
      if (BoxHeightArr[i] === minHeight) {//当图片高度等于最小高度时,该图片的位置为最小高度图片的位置
        return i
      }
    }
  }

6. 插图

for (var i = 0; i < ccontent.length; i++) {
    if (i < num) {
      BoxHeightArr[i] = ccontent[i].offsetHeight
    } else {
      var minHeight = Math.min.apply(null, BoxHeightArr)
      var minIndex = getMinHeightLocation(BoxHeightArr, minHeight)
      ccontent[i].style.position = 'absolute'//将要插入的图片绝对定位,即元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定
      ccontent[i].style.top = minHeight + 'px'//令插入的图片到顶端的距离刚好等于要插其下面图片的高度
      ccontent[i].style.left = ccontent[minIndex].offsetLeft + 'px'//令插入的图片到最左边的距离刚好等于要插其下面图片到最左边的距离
      BoxHeightArr[minIndex] = BoxHeightArr[minIndex] + ccontent[i].offsetHeight//插入图片后,得将这位置的高度设为两张图片的高度和
    }
  }

完整代码如下:

优化代码,提高性能

window.onload = function() {
  imgLocation('container', 'box')//构造函数imgLocation
}
//用window.onload = function() {}函数就不用等着body页面中调用就可以执行了

// 获取到当前有多少张图片要摆放
function imgLocation(parent, content) {//令parent='container',content='box'
  // 将parent下所有的内容全部取出
  var cparent = document.getElementById(parent)
  var ccontent = getChildElemnt(cparent, content)
  var imgWidth = ccontent[0].offsetWidth
  var num = Math.floor(document.documentElement.clientWidth / imgWidth)
  cparent.style.cssText = `width: ${imgWidth * num} px`

  var BoxHeightArr = []
  for (var i = 0; i < ccontent.length; i++) {
    if (i < num) {
      BoxHeightArr[i] = ccontent[i].offsetHeight
    } else {
      var minHeight = Math.min.apply(null, BoxHeightArr)
      var minIndex = getMinHeightLocation(BoxHeightArr, minHeight)
      ccontent[i].style.position = 'absolute'
      ccontent[i].style.top = minHeight + 'px'
      ccontent[i].style.left = ccontent[minIndex].offsetLeft + 'px'
      BoxHeightArr[minIndex] = BoxHeightArr[minIndex] + ccontent[i].offsetHeight
    }
  }
  // console.log(BoxHeightArr);
}


function getChildElemnt(parent, content) {parent='container',content='box'
  const contentArr = []
  const allContent = parent.getElementsByTagName('*')
  console.log(allContent);
  for (var i = 0; i < allContent.length; i++) {
    if (allContent[i].className == content) {
      contentArr.push(allContent[i])
    }
  }
  console.log(contentArr);
  return contentArr
}

function getMinHeightLocation(BoxHeightArr, minHeight) {
  for (var i in BoxHeightArr) {
    if (BoxHeightArr[i] === minHeight) {
      return i
    }
  }
}

以上就是如何用JS实现网页瀑布流布局的详细内容,更多关于JS实现网页瀑布流布局的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
javascript 面向对象编程基础:继承
Aug 21 Javascript
JavaScript在for循环中绑定事件解决事件参数不同的情况
Jan 20 Javascript
jQuery+css3实现转动的正方形效果(附demo源码下载)
Jan 27 Javascript
JavaScript中解决多浏览器兼容性23个问题的快速解决方法
May 19 Javascript
js定义类的几种方法(推荐)
Jun 08 Javascript
获取input标签的所有属性的方法
Jun 28 Javascript
js 获取图像缩放后的实际宽高,位置等信息
Mar 07 Javascript
Vue打包后出现一些map文件的解决方法
Feb 13 Javascript
layui结合form,table的全选、反选v1.0示例讲解
Aug 15 Javascript
Vue.use()在new Vue() 之前使用的原因浅析
Aug 26 Javascript
js前端如何写一个精确的倒计时代码
Oct 25 Javascript
8个JS的reduce使用实例和reduce操作方式
Oct 05 Javascript
分享几个JavaScript运算符的使用技巧
Apr 24 #Javascript
JavaScript 防篡改对象的用法示例
Apr 24 #Javascript
jquery插件实现悬浮的菜单
jquery插件实现代码雨特效
Apr 24 #jQuery
jquery插件实现搜索历史
Apr 24 #jQuery
关于Javascript闭包与应用的详解
vue首次渲染全过程
You might like
完美解决thinkphp验证码出错无法显示的方法
2014/12/09 PHP
PHP入门教程之会话控制技巧(cookie与session)
2016/09/11 PHP
详解PHP安装mysql.so扩展的方法
2016/12/31 PHP
PHP面向对象之工作单元(实例讲解)
2017/06/26 PHP
php使用redis的有序集合zset实现延迟队列应用示例
2020/02/20 PHP
js中将字符串转换成json的三种方式
2011/01/12 Javascript
Jquery和JS用外部变量获取Ajax返回的参数值的方法实例(超简单)
2013/06/17 Javascript
判断一个对象是否为jquery对象的方法
2014/03/12 Javascript
jQuery $命名冲突解决方案汇总
2014/11/13 Javascript
Javascript之面向对象--方法
2016/12/02 Javascript
详谈表单格式化插件jquery.serializeJSON
2017/06/23 jQuery
JavaScript判断浏览器和hack滚动条的写法
2017/07/23 Javascript
jQuery实现浏览器之间跳转并传递参数功能【支持中文字符】
2018/03/28 jQuery
浅谈Webpack下多环境配置的思路
2018/06/27 Javascript
深入浅析Node.js 事件循环、定时器和process.nextTick()
2018/10/22 Javascript
vue tab滚动到一定高度,固定在顶部,点击tab切换不同的内容操作
2020/07/22 Javascript
python解析xml文件实例分享
2013/12/04 Python
python爬取淘宝商品详情页数据
2018/02/23 Python
详解用python生成随机数的几种方法
2019/08/04 Python
python中的反斜杠问题深入讲解
2019/08/12 Python
使用 Python 遍历目录树的方法
2020/02/29 Python
哪些是python中web开发框架
2020/06/17 Python
Python下载的11种姿势(小结)
2020/11/18 Python
Keras保存模型并载入模型继续训练的实现
2021/02/20 Python
Smallable意大利家庭概念店:设计师童装及家居装饰
2018/01/08 全球购物
Sephora丝芙兰印尼官方网站:购买化妆品和护肤品
2018/07/02 全球购物
Farah官方网站:男士服装及配件
2019/11/01 全球购物
绝对经典成功的大学生推荐信
2013/11/08 职场文书
职业教育毕业生求职信
2013/11/09 职场文书
趣味游戏活动方案
2014/02/07 职场文书
《新型玻璃》教学反思
2014/04/13 职场文书
2014年行风建设工作总结
2014/12/01 职场文书
现场施工员岗位职责
2015/04/11 职场文书
2016秋季田径运动会广播稿
2015/12/21 职场文书
工人先锋号事迹材料(2016精选版)
2016/03/01 职场文书
学生早退检讨书(范文)
2019/08/19 职场文书