基于JavaScript实现瀑布流布局(二)


Posted in Javascript onJanuary 26, 2016

本文实例讲解了JavaScript实现瀑布流布局详细代码,分享给大家供大家参考,具体内容如下

1.建立Html模版

想法是先用一个div container承载所有内容,然后div box用来放置图片,最后div box_border来当图片框,代码如下

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>瀑布流</title>
</head>
<body>
  <div class="container" id="container">
    <div class="box_border" id="box_border">

      <div class="box" id="box1">
        <img src="image/01.jpg">
      </div>
  <!--把Box复制多份,这里因为代码重复省略了-->
    </div>
  </div>
</body>
</html>

2.通过css简单设置样式

主要设置水平放置,相框颜色,边界之类的

/*
边界不留空,背景黑灰
*/
body{
  margin: 0px;
  background: darkgray;
}
/*
总布局设置为相对布局
*/
.container{
  position: relative;
}
/*
设置box属性
*/
.box{
  padding: 5px;
  float: left;
}
/*设置图片边框阴影和圆角
*/
.box_border{
  padding: 5px;
  border: 1px solid #cccccc;
  box-shadow: 0px 0px 5px #ccc;
  border-radius: 5px;
}
/*设置图片格式*/
.box_border img{
  width: 150px;
  height: auto;
}

3.JS控制每一行所摆放的图片个数

上面的css布局之后,浏览器窗口大小改变,里面的图片数量也会改变,现在要用JS固定住每一行的图片数量,对于不同尺寸的屏幕都能做到很好的效果

/*
 用于加载其他函数
 */
window.onload = function(){
  setImgLocation("container");
}
/*
 设置图片个数
 */
function setImgLocation(parent){
  var cparent = document.getElementById(parent);//得到父节点
  var childArray = getChildNodes(cparent);//得到图片数量
  var imgWidth = childArray[0].offsetWidth;//获取照片宽度
  var screenWidth = document.documentElement.clientWidth;//获取浏览器宽度
  var count = Math.floor(screenWidth/imgWidth);//每行的个数
  cparent.style.cssText = "width:"+count*imgWidth+"px;margin: 0 auto;";//设置其宽度并居中

}


/*
 获取全部图片的个数
 */
function getChildNodes(parent){
  var childArray =[];//定义一个数组存放图片box
  var tempNodes = parent.getElementsByTagName("*");//获取父节点下的所有节点
  //循环添加class为box的节点
  for(var i = 0;i<tempNodes.length;i++){
    if(tempNodes[i].className == "box"){
      childArray.push(tempNodes[i]);
    }
  }
  return childArray;//返回所有的子节点
}
注意:针对不同屏幕大小显示的个数是不一样的

4.JS实现静态瀑布流

先实现静态的布局,也就是浏览器下拉不会自动刷新出新的图片.
实现排列算法很简单

  • 1.把第一排图片的高度全部存到一个数组
  • 2.计算出第一排中的图片的最小高度和对应位置
  • 3.把第一排之后的第一个图片放到该位置上
  • 4.重新设置该位置的高度为两个图片相加
  • 5.循环2剩余全部图片

代码:

/*
 用于加载其他函数
 */
window.onload = function(){
  setImgLocation("container");
}
/*
 设置图片个数及位置排列
 */
function setImgLocation(parent){
  var cparent = document.getElementById(parent);//得到父节点
  var childArray = getChildNodes(cparent);//得到图片数量
  var imgWidth = childArray[0].offsetWidth;//获取照片宽度
  var screenWidth = document.documentElement.clientWidth;//获取浏览器宽度
  var count = Math.floor(screenWidth/imgWidth);//每行的个数
  cparent.style.cssText = "width:"+count*imgWidth+"px;margin: 0 auto;";//设置其宽度并居中
  //定义数组,存放第一行照片高度
  var imgHArray = [];
  //循环遍历图片
  for(var i=0;i<childArray.length;i++){
    //如果图片在第一行则获取高度
    if(i<count){
      imgHArray[i] = childArray[i].offsetHeight;
    }else//否则把最小高度的填充剩余图片
    {
      var minHeight = Math.min.apply(null,imgHArray);//获取最小高度
      var minIndex = getMinIndex(minHeight,imgHArray);//获取最小高度对应的下标
      childArray[i].style.position = "absolute";//设置要填充的图片盒子为绝对布局,否则不能更换位置
      childArray[i].style.top = minHeight+"px";//设置要填充图片距顶高度
      childArray[i].style.left = childArray[minIndex].offsetLeft+"px";//设置要填充图片距左高度
      imgHArray[minIndex] += childArray[i].offsetHeight;//填充后把当前位置高度设为两个图片相加
      //开始下一轮循环
    }

  }

}
/*
 获取最小高度对应的下标
 */
function getMinIndex(minHeight,imgHArray){
  for(var i in imgHArray){
    if(imgHArray[i] == minHeight){
      return i;
    }
  }
}
/*
 获取全部图片的个数
 */
function getChildNodes(parent){
  var childArray =[];//定义一个数组存放图片box
  var tempNodes = parent.getElementsByTagName("*");//获取父节点下的所有节点
  //循环添加class为box的节点
  for(var i = 0;i<tempNodes.length;i++){
    if(tempNodes[i].className == "box"){
      childArray.push(tempNodes[i]);
    }
  }
  return childArray;//返回所有的子节点
}

5.js实现动态加载

动态加载也就是滚动条永远滑不到底部,要解决动态加载我们需要考虑两个问题:
1).什么时候加载?
滑动距离+浏览器高度>最后一张图片距离顶部的距离
2).怎样加载?
通过创建新的节点,把创建的节点添加进去即可
最终代码:

/*
 用于加载其他函数
 */
window.onload = function() {
  var cparent = document.getElementById("container");//得到父节点
  setImgLocation(cparent);
  //设置加载的图片
  var data = ["image/01.jpg", "image/02.jpg", "image/03.jpg", "image/04.jpg", "image/05.jpg", "image/06.jpg", "image/07.jpg", "image/08.jpg", "image/09.jpg",
    "image/11.jpg", "image/12.jpg", "image/13.jpg", "image/14.jpg", "image/15.jpg", "image/16.jpg", "image/17.jpg"];
  //滑动监听
  window.onscroll = function () {
    if (checkLoad(cparent)) {
      for (var i = 0; i < data.length; i++) {
        //创建新的节点
        var div1 = document.createElement("div");
        div1.className = "box";
        var div2 = document.createElement("div");
        div2.className = "box_border";
        var img = document.createElement("img");
        img.className = ".box_border img";
        img.src = data[i];
        div2.appendChild(img);
        div1.appendChild(div2);
        cparent.appendChild(div1);
      }
      setImgLocation(cparent);//创建节点后重新排列
    }
  }
}


/*
检查是否应该加载
 */
function checkLoad(cparent){
  var childArray = getChildNodes(cparent);//得到图片个数
  var lastImgHight = childArray[childArray.length-1].offsetTop;//得到最后一张图片距离顶部高度
  var scrollHeight = document.documentElement.scrollTop||document.body.scrollTop;//获得滑动距离(浏览器兼容性真烦人)
  var browserHeight = document.documentElement.clientHeight;//获得浏览器高度
  if(lastImgHight < scrollHeight+browserHeight){//判断是否加载
    return true;
  }else {
    return false;
  }
}
/*
 设置图片个数及位置排列
 */
function setImgLocation(cparent){

  var childArray = getChildNodes(cparent);//得到图片数量
  var imgWidth = childArray[0].offsetWidth;//获取照片宽度
  var browserWidth = document.documentElement.clientWidth;//获取浏览器宽度
  var count = Math.floor(browserWidth/imgWidth);//每行的个数
  cparent.style.cssText = "width:"+count*imgWidth+"px;margin: 0 auto;";//设置其宽度并居中
  //定义数组,存放第一行照片高度
  var imgHArray = [];
  //循环遍历图片
  for(var i=0;i<childArray.length;i++){
    //如果图片在第一行则获取高度
    if(i<count){
      imgHArray[i] = childArray[i].offsetHeight;
    }else//否则把最小高度的填充剩余图片
    {
      var minHeight = Math.min.apply(null,imgHArray);//获取最小高度
      var minIndex = getMinIndex(minHeight,imgHArray);//获取最小高度对应的下标
      childArray[i].style.position = "absolute";//设置要填充的图片盒子为绝对布局,否则不能更换位置
      childArray[i].style.top = minHeight+"px";//设置要填充图片距顶高度
      childArray[i].style.left = childArray[minIndex].offsetLeft+"px";//设置要填充图片距左高度
      imgHArray[minIndex] += childArray[i].offsetHeight;//填充后把当前位置高度设为两个图片相加
      //开始下一轮循环
    }

  }

}
/*
 获取最小高度对应的下标
 */
function getMinIndex(minHeight,imgHArray){
  for(var i in imgHArray){
    if(imgHArray[i] == minHeight){
      return i;
    }
  }
}
/*
 获取全部图片的个数
 */
function getChildNodes(parent){
  var childArray =[];//定义一个数组存放图片box
  var tempNodes = parent.getElementsByTagName("*");//获取父节点下的所有节点
  //循环添加class为box的节点
  for(var i = 0;i<tempNodes.length;i++){
    if(tempNodes[i].className == "box"){
      childArray.push(tempNodes[i]);
    }
  }
  return childArray;//返回所有的子节点
}

希望本文所述对大家学习javascript程序设计有所帮助。

Javascript 相关文章推荐
根据判断浏览器类型屏幕分辨率自动调用不同CSS的代码
Feb 22 Javascript
基于jQuery的倒计时插件代码
May 07 Javascript
线路分流自动智能跳转代码,自动选择最快镜像网站(js)
Oct 31 Javascript
jQuery实现锚点scoll效果实例分析
Mar 10 Javascript
javascript的几种写法总结
Sep 30 Javascript
js实现多张图片延迟加载效果
Jul 17 Javascript
vue.js 嵌套循环、if判断、动态删除的实例
Mar 07 Javascript
在Vue中获取组件声明时的name属性方法
Sep 12 Javascript
JavaScript 判断数据类型的4种方法
Sep 11 Javascript
JavaScript实现点击切换验证码及校验
Jan 10 Javascript
JS数组索引检测中的数据类型问题详解
Jan 11 Javascript
TS 类型收窄教程示例详解
Sep 23 Javascript
AngualrJS中每次$http请求时的一个遮罩层Directive
Jan 26 #Javascript
JavaScript html5 canvas画布中删除一个块区域的方法
Jan 26 #Javascript
HTML5游戏引擎LTweenLite实现的超帅动画效果(附demo源码下载)
Jan 26 #Javascript
jQuery form插件的使用之处理server返回的JSON, XML,HTML数据
Jan 26 #Javascript
JavaScript+html5 canvas绘制缤纷多彩的三角形效果完整实例
Jan 26 #Javascript
JavaScript+html5 canvas制作的百花齐放效果完整实例
Jan 26 #Javascript
JavaScript+html5 canvas绘制渐变区域完整实例
Jan 26 #Javascript
You might like
超神学院:天使彦公认最美的三个视角,网友:我的天使快下凡吧!
2020/03/02 国漫
从一个不错的留言本弄的mysql数据库操作类
2007/09/02 PHP
实用PHP会员权限控制实现原理分析
2011/05/29 PHP
codeigniter教程之上传视频并使用ffmpeg转flv示例
2014/02/13 PHP
PHP curl 抓取AJAX异步内容示例
2014/09/09 PHP
基于jquery插件实现常见的幻灯片效果
2013/11/01 Javascript
基于Bootstrap的UI扩展 StyleBootstrap
2016/06/17 Javascript
javascript跨域请求包装函数与用法示例
2016/11/03 Javascript
微信小程序开发之圆形菜单 仿建行圆形菜单实例
2016/12/12 Javascript
JS 中LocalStorage和SessionStorage的使用
2017/08/17 Javascript
VUE页面中加载外部HTML的示例代码
2017/09/20 Javascript
详解vue-cli 脚手架 安装
2019/04/16 Javascript
Python实现获取某天是某个月中的第几周
2015/02/11 Python
将TensorFlow的模型网络导出为单个文件的方法
2018/04/23 Python
python中plot实现即时数据动态显示方法
2018/06/22 Python
Python学习笔记之While循环用法分析
2019/08/14 Python
Python 字符串、列表、元组的截取与切片操作示例
2019/09/17 Python
django使用F方法更新一个对象多个对象字段的实现
2020/03/28 Python
Python SQLAlchemy库的使用方法
2020/10/13 Python
XML文档面试题
2015/08/05 面试题
什么是静态路由?什么是动态路由?各自的特点是什么?
2015/09/16 面试题
介绍一下EJB的体系结构
2012/08/01 面试题
岗位职责的含义
2013/11/17 职场文书
娱乐节目策划方案
2014/06/10 职场文书
单位委托书怎么写
2014/08/02 职场文书
餐饮周年庆活动方案
2014/08/14 职场文书
纪检干部现实表现材料
2014/08/21 职场文书
4s店活动策划方案
2014/08/25 职场文书
班级元旦晚会开幕词
2015/01/29 职场文书
最美乡村教师观后感
2015/06/11 职场文书
毕业生求职自荐信(2016最新版)
2016/01/28 职场文书
忆童年!用Python实现愤怒的小鸟游戏
2021/06/07 Python
python库sklearn常用操作
2021/08/23 Python
详解Nginx 被动检查服务器的存活状态
2021/10/16 Servers
python 单机五子棋对战游戏
2022/04/28 Python
安装Windows Server 2012 R2企业版操作系统并设置好相关参数
2022/04/29 Servers