如何用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 相关文章推荐
事件绑定之小测试  onclick &amp;&amp; addEventListener
Jul 31 Javascript
Javascript设置对象的ReadOnly属性(示例代码)
Dec 25 Javascript
使用AngularJS来实现HTML页面嵌套的方法
Jun 17 Javascript
JS延时提示框实现方法详解
Nov 26 Javascript
jQuery右下角悬浮广告实例
Oct 17 Javascript
文件上传插件SWFUpload的使用指南
Nov 29 Javascript
JS实现深度优先搜索求解两点间最短路径
Jan 17 Javascript
VUE中使用MUI方法
Feb 12 Javascript
node.js处理前端提交的GET请求
Aug 30 Javascript
JavaScript函数Call、Apply原理实例解析
Feb 17 Javascript
javascript实现简单搜索功能
Mar 26 Javascript
JS倒计时两种实现方式代码实例
Jul 27 Javascript
分享几个JavaScript运算符的使用技巧
Apr 24 #Javascript
JavaScript 防篡改对象的用法示例
Apr 24 #Javascript
jquery插件实现悬浮的菜单
jquery插件实现代码雨特效
Apr 24 #jQuery
jquery插件实现搜索历史
Apr 24 #jQuery
关于Javascript闭包与应用的详解
vue首次渲染全过程
You might like
在PHP中利用XML技术构造远程服务(下)
2006/10/09 PHP
php生成文件
2007/01/15 PHP
Excel数据导入Mysql数据库的实现代码
2008/06/05 PHP
PHP自定义函数判断是否为Get、Post及Ajax提交的方法
2017/07/27 PHP
phpStudy中升级MySQL版本到5.7.17的方法步骤
2017/08/03 PHP
通过Jscript中@cc_on 语句识别IE浏览器及版本的代码
2011/05/07 Javascript
关于JS字符串函数String.replace()
2013/04/07 Javascript
location对象的属性和方法应用(解析URL)
2013/04/12 Javascript
jQuery - css() 方法示例详解
2014/01/16 Javascript
Jquery解析Json格式数据过程代码
2014/10/17 Javascript
javascript使用call调用微信API
2014/12/15 Javascript
原生 JS Ajax,GET和POST 请求实例代码
2016/06/08 Javascript
jQuery内存泄露解决办法
2016/12/13 Javascript
微信小程序通过api接口将json数据展现到小程序示例
2017/01/20 Javascript
jquery对象与DOM对象转化
2017/02/08 Javascript
Vue中建立全局引用或者全局命令的方法
2017/08/21 Javascript
一文让你彻底搞清楚javascript中的require、import与export
2017/09/24 Javascript
Node.js事件的正确使用方法
2019/04/05 Javascript
Vue2(三)实现子菜单展开收缩,带动画效果实现方法
2019/04/28 Javascript
用Nodejs实现在终端中炒股的实现
2020/10/18 NodeJs
jQuery插件实现图片轮播效果
2020/10/19 jQuery
Webpack3+React16代码分割的实现
2021/03/03 Javascript
[06:43]DAC2018 4.5 SOLO赛 Maybe vs Paparazi
2018/04/06 DOTA
Python 除法小技巧
2008/09/06 Python
从零学python系列之从文件读取和保存数据
2014/05/23 Python
Python解决鸡兔同笼问题的方法
2014/12/20 Python
Python编程中的for循环语句学习教程
2015/10/14 Python
详解python tkinter包获取本地绝对路径(以获取图片并展示)
2020/09/04 Python
《雪地里的小画家》教学反思
2014/02/22 职场文书
警察先进个人事迹材料
2014/05/16 职场文书
毕业实习计划书
2015/01/16 职场文书
见习期个人总结
2015/03/05 职场文书
毕业典礼致辞
2015/07/29 职场文书
南阳市白酒市场的调查报告
2019/11/08 职场文书
Python 数据可视化工具 Pyecharts 安装及应用
2022/04/20 Python
Win11自动黑屏怎么办 Win11自动黑屏设置教程
2022/07/15 数码科技