如何用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 相关文章推荐
jquery实现心算练习代码
Dec 06 Javascript
js实现上传图片预览的方法
Feb 09 Javascript
arguments对象验证函数的参数是否合法
Jun 26 Javascript
深入学习jQuery Validate表单验证(二)
Jan 18 Javascript
详解JavaScript中双等号引起的隐性类型转换
May 30 Javascript
jQuery模仿京东/天猫商品左侧分类导航菜单效果
Jun 29 Javascript
Angular.js自动化测试之protractor详解
Jul 07 Javascript
基于jquery trigger函数无法触发a标签的两种解决方法
Jan 06 jQuery
Vue项目查看当前使用的elementUI版本的方法
Sep 27 Javascript
JavaScript设计模式--简单工厂模式实例分析【XHR工厂案例】
May 23 Javascript
vue router返回到指定的路由的场景分析
Nov 10 Javascript
vue+Element-ui前端实现分页效果
Nov 15 Javascript
分享几个JavaScript运算符的使用技巧
Apr 24 #Javascript
JavaScript 防篡改对象的用法示例
Apr 24 #Javascript
jquery插件实现悬浮的菜单
jquery插件实现代码雨特效
Apr 24 #jQuery
jquery插件实现搜索历史
Apr 24 #jQuery
关于Javascript闭包与应用的详解
vue首次渲染全过程
You might like
深入了解php4(2)--重访过去
2006/10/09 PHP
修改PHP脚本使WordPress拦截垃圾评论的方法示例
2015/12/10 PHP
Yii2中DropDownList简单用法示例
2016/07/18 PHP
Yii框架结合sphinx,Ajax实现搜索分页功能示例
2016/10/18 PHP
PHP将字符串首字母大小写转换的实例
2017/01/21 PHP
PHP利用百度ai实现文本和图片审核
2019/05/08 PHP
js 动态文字滚动的例子
2011/01/17 Javascript
js获取location.href的参数实例代码
2013/08/02 Javascript
JQuery插件iScroll实现下拉刷新,滚动翻页特效
2014/06/22 Javascript
jQuery动态生成不规则表格(前后端)
2017/02/21 Javascript
JS实现双击内容变为可编辑状态
2017/03/03 Javascript
JavaScript实现分页效果
2017/03/28 Javascript
vue webpack打包优化操作技巧
2018/02/22 Javascript
三分钟学会用ES7中的Async/Await进行异步编程
2018/06/14 Javascript
在小程序中推送模板消息的实现方法
2019/07/22 Javascript
基于vue-cli3创建libs库的实现方法
2019/12/04 Javascript
微信小程序学习总结(三)条件、模板、文件引用实例分析
2020/06/04 Javascript
[01:34]DAC2018主赛事第四日五佳镜头 Gh巨牙海民助Miracle-死里逃生
2018/04/07 DOTA
进一步理解Python中的函数编程
2015/04/13 Python
python http接口自动化脚本详解
2018/01/02 Python
Python中常用信号signal类型实例
2018/01/25 Python
详解Python中where()函数的用法
2018/03/27 Python
python版本的仿windows计划任务工具
2018/04/30 Python
python 将列表中的字符串连接成一个长路径的方法
2018/10/23 Python
Python3爬虫学习之MySQL数据库存储爬取的信息详解
2018/12/12 Python
梅尔倒谱系数(MFCC)实现
2019/06/19 Python
pytorch 实现查看网络中的参数
2020/01/06 Python
python opencv肤色检测的实现示例
2020/12/21 Python
Pytorch如何切换 cpu和gpu的使用详解
2021/03/01 Python
css3过渡_动力节点Java学院整理
2017/07/11 HTML / CSS
联想印度官方网上商店:Lenovo India
2019/08/24 全球购物
软件测试英文面试题
2012/10/14 面试题
大一学生假期实习的自我评价
2013/10/12 职场文书
小区门卫工作职责
2013/12/14 职场文书
污水处理保证书
2015/05/09 职场文书
小学教学工作总结2015
2015/05/13 职场文书