如何用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的可以控制左右滚动及自动滚动效果的代码
Jul 25 Javascript
jquery实现简单手风琴菜单效果实例
Jun 13 Javascript
js css自定义分页效果
Feb 24 Javascript
xmlplus组件设计系列之图标(ICON)(1)
May 05 Javascript
vue 怎么创建组件及组件使用方法
Jul 27 Javascript
用js实现before和after伪类的样式修改的示例代码
Sep 07 Javascript
webpack实用小功能介绍
Jan 02 Javascript
小程序rich-text组件如何改变内部img图片样式的方法
May 22 Javascript
Vue+Typescript中在Vue上挂载axios使用时报错问题
Aug 07 Javascript
解决Vue-Router升级导致的Uncaught (in promise)问题
Aug 07 Javascript
javascript实现一款好看的秒表计时器
Sep 05 Javascript
分享几个JavaScript运算符的使用技巧
Apr 24 Javascript
分享几个JavaScript运算符的使用技巧
Apr 24 #Javascript
JavaScript 防篡改对象的用法示例
Apr 24 #Javascript
jquery插件实现悬浮的菜单
jquery插件实现代码雨特效
Apr 24 #jQuery
jquery插件实现搜索历史
Apr 24 #jQuery
关于Javascript闭包与应用的详解
vue首次渲染全过程
You might like
php checkdate、getdate等日期时间函数操作详解
2010/03/11 PHP
Thinkphp中Create方法深入探究
2014/06/16 PHP
php similar_text()函数的定义和用法
2016/05/12 PHP
jQuery 剧场版 你必须知道的javascript
2009/05/27 Javascript
IE10中flexigrid无法显示数据的解决方法
2015/07/26 Javascript
浅谈JavaScript超时调用和间歇调用
2015/08/30 Javascript
JavaScript中Boolean对象的属性解析
2015/10/21 Javascript
jQuery属性选择器用法示例
2016/09/09 Javascript
微信小程序 教程之wxapp视图容器 swiper
2016/10/19 Javascript
JavaScript在控件上添加倒计时功能的实现代码
2017/07/04 Javascript
Js面试算法详解
2018/04/08 Javascript
vue :src 文件路径错误问题的解决方法
2018/05/15 Javascript
vue项目中使用Hbuilder打包app 设置沉浸式状态栏的方法
2018/10/22 Javascript
Vue.js特性Scoped Slots的浅析
2019/02/20 Javascript
微信小程序第三方框架对比 之 wepy / mpvue / taro
2019/04/10 Javascript
一篇文章介绍redux、react-redux、redux-saga总结
2019/05/23 Javascript
vue props对象validator自定义函数实例
2019/11/13 Javascript
webpack5 联邦模块介绍详解
2020/07/08 Javascript
Python标准异常和异常处理详解
2015/02/02 Python
Python的Flask框架的简介和安装方法
2015/11/13 Python
Python文本统计功能之西游记用字统计操作示例
2018/05/07 Python
python 匹配url中是否存在IP地址的方法
2018/06/04 Python
python自定义线程池控制线程数量的示例
2019/02/22 Python
django项目中新增app的2种实现方法
2020/04/01 Python
keras的ImageDataGenerator和flow()的用法说明
2020/07/03 Python
HTML5语音识别标签写法附图
2013/11/18 HTML / CSS
标准自荐信范文
2014/01/29 职场文书
人力资源部门的主要职能
2014/02/22 职场文书
《桥》教学反思
2014/04/09 职场文书
2014年党务公开方案
2014/05/08 职场文书
法制宣传教育方案
2014/05/09 职场文书
2014年政协委员工作总结
2014/12/01 职场文书
辛德勒的名单观后感
2015/06/03 职场文书
拔河比赛新闻稿
2015/07/17 职场文书
2015毕业设计工作总结
2015/07/24 职场文书
为什么阅读对所有年龄段的孩子都很重要?
2019/07/08 职场文书