如何用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实现2048游戏示例
May 04 Javascript
Javascript基础教程之switch语句
Jan 18 Javascript
12种JavaScript常用的MVC框架比较分析
Nov 16 Javascript
JavaScript+html5 canvas绘制缤纷多彩的三角形效果完整实例
Jan 26 Javascript
vue 和vue-touch 实现移动端左右导航效果(仿京东移动站导航)
Apr 22 Javascript
浅谈jQuery框架Ajax常用选项
Jul 08 jQuery
深入理解vue $refs的基本用法
Jul 13 Javascript
前端axios下载excel文件(二进制)的处理方法
Jul 31 Javascript
详解小程序输入框闪烁及重影BUG解决方案
Aug 31 Javascript
Windows下Node爬虫神器Puppeteer安装记
Jan 09 Javascript
Vue实现导航栏菜单
Aug 19 Javascript
js+h5 canvas实现图片验证码
Oct 11 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 入门学习资料
2011/01/01 PHP
PHP函数篇详解十进制、二进制、八进制和十六进制转换函数说明
2011/12/05 PHP
深入分析使用mysql_fetch_object()以对象的形式返回查询结果
2013/06/05 PHP
golang、python、php、c++、c、java、Nodejs性能对比
2017/03/12 NodeJs
thinkphp下MySQL数据库读写分离代码剖析
2017/04/18 PHP
浅谈关于PHP解决图片无损压缩的问题
2017/09/01 PHP
thinkphp ajaxfileupload实现异步上传图片的示例
2017/08/28 PHP
使用JS操作页面表格,元素的一些技巧
2007/02/02 Javascript
使用js判断数组中是否包含某一元素(类似于php中的in_array())
2013/12/12 Javascript
JS给swf传参数的实现方法
2016/09/13 Javascript
Angularjs中三种数据的绑定策略(“@”,“=”,“&amp;”)
2016/12/23 Javascript
详解Python中logging日志模块在多进程环境下的使用
2016/12/26 Javascript
js实现滑动到页面底部自动加载更多功能
2017/02/15 Javascript
canvas实现爱心和彩虹雨效果
2017/03/09 Javascript
详解Vue2.0里过滤器容易踩到的坑
2017/06/01 Javascript
解决canvas画布使用fillRect()时高度出现双倍效果的问题
2017/08/03 Javascript
详解react关于事件绑定this的四种方式
2018/03/09 Javascript
jQuery实现使用sort方法对json数据排序的方法
2018/04/17 jQuery
WebSocket的简单介绍及应用
2019/05/23 Javascript
jquery css实现流程进度条
2020/03/26 jQuery
[01:29:42]Liquid vs VP Supermajor决赛 BO 第一场 6.10
2018/07/05 DOTA
跟老齐学Python之大话题小函数(2)
2014/10/10 Python
Python实现爬取逐浪小说的方法
2015/07/07 Python
Python中使用插入排序算法的简单分析与代码示例
2016/05/04 Python
数据清洗--DataFrame中的空值处理方法
2018/07/03 Python
python爬虫 线程池创建并获取文件代码实例
2019/09/28 Python
基于python cut和qcut的用法及区别详解
2019/11/22 Python
CSS3近阶段篇之酷炫的3D旋转透视
2016/04/28 HTML / CSS
HTML5新增属性data-*和js/jquery之间的交互及注意事项
2017/08/08 HTML / CSS
大家访活动实施方案
2014/03/10 职场文书
大学生自我鉴定书
2014/03/24 职场文书
党的群众路线教育实践活动整改落实情况报告
2014/10/28 职场文书
2014年应急工作总结
2014/12/11 职场文书
感动中国何玥观后感
2015/06/02 职场文书
运动会5000米加油稿
2015/07/21 职场文书
关于JavaScript回调函数的深入理解
2021/06/27 Javascript