前言:

瀑布流 又称瀑布流式布局,是比较流行的一种网站页面布局方式。即多行等宽元素排列,后面的元素依次添加到其后,等宽不等高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置。

什么是瀑布流布局:

先看效果:

  • 图片多行等宽元素排列,后面的元素依次添加到其后,等宽不等高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置。
  • 为了方便理解,在此先给上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实现网页瀑布流布局的资料请关注程序员的世界其它相关文章!

如何用JS实现网页瀑布流布局的更多相关文章

  1. JavaScript this关键字的深入详解

    一、前言this关键字是JavaScript中最复杂的机制之一。它是一个很特别的关键字,被自动定义在所有函数的作用域中。对于那些没有投入时间学习this机制的JavaScript开发者来说,this的绑定一直是一件非常令人困惑的事。二、了解this学习this的第一步是明白this既不指向函数自身也......

  2. 详解CocosCreator制作射击游戏

    场景布置游戏资源炮塔旋转机制与之前手柄实例的小车相同,使用touchmove监听触摸事件,获取触摸位置通过位置用signAngle方法将该位置与cc.v2(1,0)位置的角度差求出(记得要加负号,比较所得逆时针为负,赋值angle逆指针为正)。所求的的角度即为最终角度。onLoad(){//初始化为......

  3. Swiper.js插件超简单实现轮播图

    Swiper是纯javascript打造的滑动特效插件,面向手机、平板电脑等移动终端。能实现触屏焦点图、触屏Tab切换、触屏多图切换等常用效果。超好用话不多说,直接上教程1、首先加载插件,需要用到的文件有swiper.min.js和swiper.min.css文件。可下载Swiper文件或使用CDN......

  4. jQuery中toggle与slideToggle以及fadeToggle的显示、隐藏方法的比较

    1、区别 ①动画效果的比较: toggle:直接显示、隐藏,如果有【时间参数】且【匹配的元素有宽度属性】,则动态效果为左上角-右下角拉卷效果,透明度0-1之间的变化;若有时间参数但是【匹配的元素没有宽度属性】,则动态效果为上下拉卷的效果,且没有透明度的变化。 slideToggle:切换上下拉卷滚效......

  5. 微信小程序自定义scroll-view的实例代码

    小程序自定义 scroll-view 滚动条话不多说, 直接上效果图效果图wxml代码<scroll-view scroll-x class="scroll-view" bindscroll="bindScroll"><block wx:fo......

  6. 文件上传漏洞全面渗透姿势总结

    文件上传漏洞全面渗透姿势总结0x00 文件上传场景(本文档只做技术交流,切勿进行违法犯罪操作,请做一个好人,不给别人添麻烦)文件上传的场景真的随处可见,不加防范小心,容易造成漏洞,造成信息泄露,甚至更为严重的灾难。比如某博客网站评论编辑模块,右上角就有支持上传图片的功能,提交带有恶意字符串的图片后,......

  7. 原生JavaScript实现轮播图

    本文实例为大家分享了JavaScript实现轮播图的具体代码,供大家参考,具体内容如下效果:代码:* {margin: 0;padding: 0;}ul,li {list-style: none;}.banner {width: 1200px;height: 535px;border: 1px so......

  8. javascript 数组(list)添加/删除的实现

    javascript 数组Array(list)添加/删除unshift:将参数添加到原数组开头,并返回数组的长度pop:删除原数组最后一项,并返回删除元素的值;如果数组为空则返回undefinedpush:将参数添加到原数组末尾,并返回数组的长度concat:返回一个新数组,是将参数添加到原数组中......

  9. JavaScript实现颜色查看器

    本文实例为大家分享了JavaScript实现颜色查看器的具体代码,供大家参考,具体内容如下实现效果方框中初始为白色输入框中输入颜色代码,点击查看颜色,在上方即可出现对应颜色点击复原,复原到初始的白色,同时清空输入框的内容实现代码<!DOCTYPE html><html lang=&......

  10. CocosCreator学习之模块化脚本

    Cocos Creator模块化脚本Cocos Creator 允许你将代码拆分成多个脚本文件,并且让它们相互调用。这个步骤简称为 模块化。模块化使你可以在 Cocos Creator 中引用其它脚本文件:访问其它文件导出的参数调用其它文件导出的方法使用其它文件导出的类型使用或继承其它 Compon......

随机推荐

  1. sqlserver 日期与字符串之间的转换

    字符转换为日期时,Style的使用--1. Style=101时,表示日期字符串为:mm/dd/yyyy格式SELECT CONVERT(datetime,'11/1/2003',101)--结果:2003-11-01 00:00:00.000--2. Style=101时,表示日期字符串为:dd/......

  2. ASP下通过Adodb.Stream实现多线程下载大文件

    有个朋友 做 某种小众音乐交换站的(他们那个行业的昵图网),需要用到付费下载。尝试过 防盗链,不太理想,最终使用了 Adodb.Stream 读取,直接输出。解决了 盗版的问题,但是新的问题又来了。Adodb.Stream 这种方式 电脑还好说,大部分电脑浏览器都支持。移动端 很多 浏览器为了 加速......

  3. 使用 gRPCurl 调试.NET 5的gPRC服务

    介绍你用过 Curl 吗?这个工具允许你通过 http 来发送数据,现在有一个适用于gGRPC的工具,gRPCurl,在本文中,我将介绍如何下载安装这个工具,然后通过这个工具调试我们.NET 5上面的gGRC程序。安装 gRPCurlgRPCurl 基于GO语言开发,所以,你要安装GO环境,可以在这......

  4. Vue实现一种简单的无限循环滚动动画的示例

    本文主要介绍了Vue实现一种简单的无限循环滚动动画的示例,分享给大家,具体如下:先看实现效果:这种类似轮播的效果,通常可以使用轮播的方案解决,只不过相对于我要分享的方案来说,轮播实现还是要复杂些的。Vue提供了一种过渡动画transition-group,这里我便是利用的这个效果// templat......

  5. Linux下Too many open files问题排查与解决

    作者:Grey原文地址:Github语雀博客园Too many open files是Linux系统中常见的错误,从字面意思上看就是说程序打开的文件数过多,不过这里的files不单是文件的意思,也包括打开的通讯链接(比如socket),正在监听的端口等等,所以有时候也可以叫做句柄(handle),这......

  6. Java中,那些关于String和字符串常量池你不得不知道的东西

    老套的笔试题在一些老套的笔试题中,会要你判断s1==s2为false还是true,s1.equals(s2)为false还是true。String s1 = new String("xyz");String s2 = "xyz";System.out.prin......

  7. JavaWeb实现文件的上传与下载

    JavaWeb实现文件的上传与下载,供大家参考,具体内容如下第一步:导包导入commons-fileupload-1.3.3.jar和commons-io-2.4.jar两个依赖包第二步:编写前端页面1、提交页面 index.jsp<%@ page language="java&qu......

  8. C# StreamReader类实现读取文件的方法

    在 C# 语言中 StreamReader 类用于从流中读取字符串。它继承自 TextReader 类。StreamReader 类的构造方法有很多,这里介绍一些常用的构造方法,如下表所示。构造方法说明StreamReader(Stream stream)为指定的流创建 StreamReader 类......

  9. oracle 11g的安装注意事项总结

    oracle 11g 安装注意事项1、首先时这个配置安全更新页面,不需要填写电子邮件,下面安全更新也取消候选,否则一旦出现软件更新,会拖慢我们的使用进度2、在安装选项这里,就选择第一个“创建和配置数据库”,就是安装完整的oracle数据库软件第二个“仅安装数据库软件”,意思就是只安装实例,并不安装数......

  10. C# Winform 实现控件自适应父容器大小

    在日常开发中经常遇到控件不能随着父容器大小的改变而且自动改变控件的所在位置和大小。以下是实现的代码/// <summary>/// 根据父容器实现控件自适应大小位置/// </summary>/// <param name="control">......