如何用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.ui.progressbar 中文文档
Nov 26 Javascript
鼠标滑上去后图片放大浮出效果的js代码
May 28 Javascript
javascript 兼容各个浏览器的事件
Feb 04 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记6)
Dec 20 Javascript
Jquery中巧用Ajax的beforeSend方法
Jan 20 Javascript
微信小程序 开发经验整理
Feb 15 Javascript
Vue中定义全局变量与常量的各种方式详解
Aug 23 Javascript
vue做网页开场视频的实例代码
Oct 20 Javascript
深入理解node.js http模块
Jan 24 Javascript
使用vue-router与v-if实现tab切换遇到的问题及解决方法
Sep 07 Javascript
微信小程序如何利用getCurrentPages进行页面传值
Jul 01 Javascript
Vue实现兄弟组件间的联动效果
Jan 21 Javascript
分享几个JavaScript运算符的使用技巧
Apr 24 #Javascript
JavaScript 防篡改对象的用法示例
Apr 24 #Javascript
jquery插件实现悬浮的菜单
jquery插件实现代码雨特效
Apr 24 #jQuery
jquery插件实现搜索历史
Apr 24 #jQuery
关于Javascript闭包与应用的详解
vue首次渲染全过程
You might like
适用于php-5.2 的 php.ini 中文版[金步国翻译]
2011/04/17 PHP
Laravel 修改验证异常的响应格式实例代码详解
2020/05/25 PHP
JavaScript 调试器简介
2009/02/21 Javascript
Jquery ThickBox插件使用心得(不建议使用)
2010/09/08 Javascript
Javascript 读取操作Sql中的Xml字段
2014/10/09 Javascript
director.js实现前端路由使用实例
2015/02/03 Javascript
iScroll中事件点击触发两次解决方案
2015/03/11 Javascript
JS实现新浪博客左侧的Blog管理菜单效果代码
2015/10/22 Javascript
原生js实现数字字母混合验证码的简单实例
2015/12/10 Javascript
Web开发必知Javascript技巧大全
2016/02/23 Javascript
Boostrap实现的登录界面实例代码
2016/10/09 Javascript
微信小程序遇到修改数据后页面不渲染的问题解决
2017/03/09 Javascript
JS正则表达式验证中文字符
2017/05/08 Javascript
JS实现留言板功能
2017/06/17 Javascript
JS实现页面打印(整体、局部)
2017/08/18 Javascript
JS实现网页抢购功能(触发,终止脚本)
2017/11/27 Javascript
easyui下拉框动态级联加载的示例代码
2017/11/29 Javascript
详解webpack import()动态加载模块踩坑
2018/07/17 Javascript
用POSTMAN发送JSON格式的POST请求示例
2018/09/04 Javascript
研究Python的ORM框架中的SQLAlchemy库的映射关系
2015/04/25 Python
各种Python库安装包下载地址与安装过程详细介绍(Windows版)
2016/11/02 Python
python使用opencv进行人脸识别
2017/04/07 Python
Python3实现简单可学习的手写体识别(实例讲解)
2017/10/21 Python
TensorFlow用expand_dim()来增加维度的方法
2018/07/26 Python
我用Python抓取了7000 多本电子书案例详解
2019/03/25 Python
Ubuntu18.04下python版本完美切换的解决方法
2019/06/14 Python
python模拟点击网页按钮实现方法
2020/02/25 Python
Django模型验证器介绍与源码分析
2020/09/08 Python
Roxy美国官网:澳大利亚冲浪、滑雪健身品牌
2016/07/30 全球购物
美国男装连锁零售商:Men’s Wearhouse
2016/10/14 全球购物
美国办公用品折扣网站:Shoplet.com
2019/11/24 全球购物
毕业生如何写自我鉴定
2014/03/15 职场文书
群众路线自查报告及整改措施
2014/11/04 职场文书
2015年污水处理厂工作总结
2015/05/26 职场文书
单位提档介绍信
2015/10/22 职场文书
python 实现定时任务的四种方式
2021/04/01 Python