javascript瀑布流布局实现方法详解


Posted in Javascript onFebruary 17, 2016

本文实例讲述了javascript瀑布流布局实现方法。分享给大家供大家参考,具体如下:

html结构:

<div id="waterfall">
  <div class="mod-box">
    <div class="mod-img">...</div>
  </div>
  <div class="mod-box">
    <div class="mod-img">...</div>
  </div>
  <div class="mod-box">
    <div class="mod-img">...</div>
  </div>
</div>

css样式表:

*{margin:0;padding: 0}
#waterfall{position: relative;}
.mod-box{
  padding: 15px 0 0 15px;
  float: left;
}
.mod-img{
  padding: 9px;
  border: 1px solid #ccc;
  border-radius: 5px;
  box-shadow: 0 0 5px #ccc;
  position: relative;
}
.mod-img img{
  width: 310px;
  height: auto;
}

javascript代码:

window.onload = function(){
   waterFall("waterfall","mod-box");
}
window.onscroll = scroll;
window.onresize = function() {
  if(re)clearTimeout(re);
  var re = setTimeout(function() {
  waterFall("waterfall","mod-box");
   }, 200);
}
var dataInit = {
  "data": [
    {
      "src": "5.jpg"
    },
    {
      "src": "6.jpg"
    }
   ]
  };
/**
 * 滚动添加数据函数
 */
function scroll(){
 var flag = checkScroll("waterfall","mod-box");
 if(flag ){
   var oparent = document.getElementById("waterfall");
   var htmlStr = "";
   var len = dataInit.data.length;
   for(var i=0;i<len;i++){
     htmlStr+=""; //需要插入的结构
   }
   oparent.innerHTML+=htmlStr;
   waterFall("waterfall","mod-box"); //重新调用一次
 }
}
/**
 * 瀑布流函数
 * @param parentID 容器id
 * @param clsName 数据块className
 */
function waterFall(parentID,clsName){
  var oParent = document.getElementById(parentID); // 父级对象
  //将content下所有class为mod-box的元素取出来
  var oBoxs = getObjsByClassName(oParent,clsName);// 获取存储块框clsName的数组oBoxs
  var oBoxWidth = oBoxs[0].offsetWidth;  //obox的宽 ==>310+9*2+2+15 = 345(包含边框和内边距) 一个块框的宽
  var pageWidth = document.documentElement.clientWidth; //页面可视宽度
  //var pageWidth = document.documentElement.offsetWidth; //页面可视宽度
  var cols = Math.floor(pageWidth/oBoxWidth); //计算整个页面显示的列数(页面宽/obox的宽)每行中能容纳的mod-box个数
  var hAarr = []; //用于存储 每列中的所有块框相加的高度。
  var minH;   
  var minHIndex;    //最小高度对应的索引值
  for(var i = 0;i<oBoxs.length;i++){//遍历数组aPin的每个块框元素
    oBoxs[i].style.position="absolute";
    if(i<cols){ //把第一行排放好,并将每一列的高度记入数据hAarr
      hAarr.push(oBoxs[i].offsetHeight);
      oBoxs[i].style.top=0+"px";
      oBoxs[i].style.left=oBoxWidth*i+"px";
    }else{
      minH = Math.min.apply(null,hAarr); //数组hAarr中的最小值minH
      minHIndex = getMinhIndex(hAarr,minH);
      oBoxs[i].style.top=minH+"px";
      // oBoxs[i].style.left=oBoxWidth*minHIndex+"px";
      oBoxs[i].style.left= oBoxs[minHIndex].offsetLeft+"px";
      //数组 最小高元素的高 + 添加上的aPin[i]块框高
      hAarr[minHIndex]+=oBoxs[i].offsetHeight; //更新添加了块框后的列高
    }
  }
  var maxH = Math.max.apply(null,hAarr);
  oParent.style.cssText = "width:"+oBoxWidth*cols+"px;margin:0 auto;height:"+maxH+"px;"; //设置父级居中样式:定宽+自动水平外边距
}
/**
 * 检查是否符合加载数据(滚动到最后一个oBox)
 * @param parentID 容器id
 * @param clsName 数据块className
 * @returns {boolean}
 */
function checkScroll(parentID,clsName){
  var parentObj = typeof parentID=="object" ?parentID:document.getElementById(parentID);
  var oBoxs = getObjsByClassName(parentObj,clsName);
  var lastBoxH = oBoxs[oBoxs.length-1].offsetTop+Math.floor(oBoxs[oBoxs.length-1].offsetHeight/2);
  //创建【触发添加块框函数waterfall()】的高度:最后一个块框的距离网页顶部+自身高的一半(实现未滚到底就开始加载)
  var scrolltop = document.body.scrollTop ||document.documentElement.scrollTop;
  //标准模式与混杂模式
  var height = document.documentElement.clientHeight; //页面高度
  return (lastBoxH<scrolltop+height)?true:false;
}
/**
 * 根据class获得元素
 * @param id
 * @param clsName
 * @returns {Array}
 */
function getObjsByClassName(parentID,clsName){
  var parentObj = typeof parentID=="object" ?parentID:document.getElementById(parentID);
  if(!parentObj){
    return;
  }
  var childObjs = parentObj.getElementsByTagName("*"); //获取 父级的所有子集
  var calssObjs = []; //创建一个数组 用于收集子元素
  for(var i in childObjs){//遍历子元素、判断类别、压入数组
    if(childObjs[i].className==clsName){ 
      calssObjs.push(childObjs[i]);
    }
  }
  return calssObjs;
}
/**
 * 获取最小值的索引minIndex
 * @param arr
 * @param minH
 * @returns {string}
 */
function getMinhIndex(arr,minH){
  for(var i in arr){
    if(arr[i]===minH){
      return i;
    }
  }
}

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

Javascript 相关文章推荐
关于Javascript 的 prototype问题。
Jan 03 Javascript
Array.prototype.slice.apply的使用方法
Mar 17 Javascript
JavaScript控制table某列不显示的方法
Mar 16 Javascript
jQuery实现指定内容滚动同时左侧或其它地方不滚动的方法
Aug 08 Javascript
详解jQuery向动态生成的内容添加事件响应jQuery live()方法
Nov 02 Javascript
jquery编写日期选择器
Mar 16 Javascript
js实现添加删除表格(两种方法)
Apr 27 Javascript
利用 spin.js 生成等待效果(js 等待效果)
Jun 25 Javascript
Vue+SpringBoot开发V部落博客管理平台
Dec 27 Javascript
Element实现表格嵌套、多个表格共用一个表头的方法
May 09 Javascript
Javascript实现简易天数计算器
May 18 Javascript
vue实现简单全选和反选功能
Sep 15 Javascript
给angular加上动画效遇到的问题总结
Feb 17 #Javascript
基于jQuery实现的无刷新表格分页实例
Feb 17 #Javascript
jQuery实现伪分页的方法分享
Feb 17 #Javascript
jQuery simplePage+AJAX plus分页插件用法实例
Feb 17 #Javascript
DeviceOne 让你一见钟情的App快速开发平台
Feb 17 #Javascript
纯JavaScript代码实现文本比较工具
Feb 17 #Javascript
JavaScript实现身份证验证代码
Feb 17 #Javascript
You might like
PHP使用ob_start生成html页面的方法
2014/11/07 PHP
php代码架构的八点注意事项
2016/01/25 PHP
twig模板获取全局变量的方法
2016/02/05 PHP
phpstudy默认不支持64位php的解决方法
2017/02/20 PHP
event.srcElement+表格应用
2006/08/29 Javascript
小议Function.apply() 之一------(函数的劫持与对象的复制)
2006/11/30 Javascript
[原创]提供复制本站内容时出现,该文章转自脚本之家等字样的js代码
2007/03/27 Javascript
几款极品的javascript压缩混淆工具
2007/05/16 Javascript
jQuery select的操作实现代码
2009/05/06 Javascript
基于JQuery的多标签实现代码
2012/09/19 Javascript
使用jQuery将多条数据插入模态框的实现代码
2014/10/08 Javascript
jQuery simplePage+AJAX plus分页插件用法实例
2016/02/17 Javascript
javascript+HTML5 Canvas绘制转盘抽奖
2020/05/16 Javascript
Node.js用readline模块实现输入输出
2016/12/16 Javascript
Typescript 中的 interface 和 type 到底有什么区别详解
2019/06/18 Javascript
更优雅的微信小程序骨架屏实现详解
2019/08/07 Javascript
Vue 实现复制功能,不需要任何结构内容直接复制方式
2019/11/09 Javascript
使用Mock.js生成前端测试数据
2020/12/13 Javascript
几个提升Python运行效率的方法之间的对比
2015/04/03 Python
Python中shutil模块的常用文件操作函数用法示例
2016/07/05 Python
使用python实现生成用户信息
2017/03/20 Python
Python Selenium 之关闭窗口close与quit的方法
2019/02/13 Python
十行代码使用Python写一个USB病毒
2019/06/21 Python
利用python-docx模块写批量生日邀请函
2019/08/26 Python
python无序链表删除重复项的方法
2020/01/17 Python
python的reverse函数翻转结果为None的问题
2020/05/11 Python
什么是python的必选参数
2020/06/21 Python
CSS3 开发工具收集
2010/04/17 HTML / CSS
详解HTML5常用的语义化标签
2019/09/27 HTML / CSS
如何将字串String转换成整数int
2015/02/21 面试题
C语言中break与continue的区别
2012/07/12 面试题
水果连锁超市创业计划书
2014/01/24 职场文书
化工专业自荐书
2014/06/16 职场文书
数学教师求职信范文
2015/03/20 职场文书
Nginx同一个域名配置多个项目的实现方法
2021/03/31 Servers
不负正版帝国之名 《重返帝国》引领SLG手游制作新的标杆
2022/04/07 其他游戏