如何用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的cookie的用法
Jan 10 Javascript
一个简单的网站访问JS计数器 刷新1次加1次访问
Sep 20 Javascript
script标签属性type与language使用选择
Dec 02 Javascript
在JavaScript中使用NaN值的方法
Jun 05 Javascript
jquery 点击元素后,滚动条滚动至该元素位置的方法
Aug 05 Javascript
微信小程序 Video API实例详解
Oct 02 Javascript
常用JS图片滚动(无缝、平滑、上下左右滚动)代码大全(推荐)
Dec 20 Javascript
vue-music关于Player播放器组件详解
Nov 28 Javascript
js实现一个简单的MVVM框架示例
Jan 15 Javascript
Javascript删除数组里的某个元素
Feb 28 Javascript
JavaScript实现多张图片放大镜效果示例【不限定图片尺寸,rem单位】
May 14 Javascript
利用JavaScript将Excel转换为JSON示例代码
Jun 14 Javascript
分享几个JavaScript运算符的使用技巧
Apr 24 #Javascript
JavaScript 防篡改对象的用法示例
Apr 24 #Javascript
jquery插件实现悬浮的菜单
jquery插件实现代码雨特效
Apr 24 #jQuery
jquery插件实现搜索历史
Apr 24 #jQuery
关于Javascript闭包与应用的详解
vue首次渲染全过程
You might like
PHP利用COM对象访问SQLServer、Access
2006/10/09 PHP
基于mysql的bbs设计(二)
2006/10/09 PHP
比较discuz和ecshop的截取字符串函数php版
2012/09/03 PHP
PHP图片水印类的封装
2017/07/06 PHP
js parsefloat parseint 转换函数
2010/01/21 Javascript
Yii-自定义删除确认弹框(zyd)jquery实现代码
2013/03/04 Javascript
JavaScript用Number方法实现string转int
2014/05/13 Javascript
javascript实现表单验证
2016/01/29 Javascript
深入理解JavaScript单体内置对象
2016/06/06 Javascript
Javascript 事件冒泡机制详细介绍
2016/10/10 Javascript
使用微信小程序开发前端【快速入门】
2016/12/05 Javascript
浅谈基于Vue.js的移动组件库cube-ui
2017/12/20 Javascript
vue全局组件与局部组件使用方法详解
2018/03/29 Javascript
使用vue-cli创建项目的图文教程(新手入门篇)
2018/05/02 Javascript
ES6之模版字符串的具体使用
2018/05/17 Javascript
使用vue-router在Vue页面之间传递数据的方法
2019/07/15 Javascript
Angular单元测试之事件触发的实现
2020/01/20 Javascript
vue抽出组件并传值实例
2020/07/31 Javascript
uniapp实现可滑动选项卡
2020/10/21 Javascript
[02:09]EHOME夺得首届辉夜杯冠军—现场颁奖仪式
2015/12/28 DOTA
python使用htmllib分析网页内容的方法
2015/05/08 Python
Python实现获取域名所用服务器的真实IP
2015/10/25 Python
Python的爬虫程序编写框架Scrapy入门学习教程
2016/07/02 Python
Python如何抓取天猫商品详细信息及交易记录
2018/02/23 Python
Python3.5面向对象编程图文与实例详解
2019/04/24 Python
Python3内置模块random随机方法小结
2019/07/13 Python
django-crontab实现服务端的定时任务的示例代码
2020/02/17 Python
Python绘图实现台风路径可视化代码实例
2020/10/23 Python
有机童装:Toby Tiger
2018/05/23 全球购物
学校课外活动总结
2014/05/08 职场文书
忠诚与背叛观后感
2015/06/04 职场文书
围城读书笔记
2015/06/26 职场文书
2016年安全月活动总结
2016/04/06 职场文书
2019年房屋委托租赁合同范本(通用版)!
2019/07/17 职场文书
竞选稿之小学班干部
2019/10/31 职场文书
Echarts如何重新渲染实例详解
2022/05/30 Javascript