纯js实现瀑布流布局及ajax动态新增数据


Posted in Javascript onApril 07, 2016

本文用纯js代码手写一个瀑布流网页效果,初步实现一个基本的瀑布流布局,以及滚动到底部后模拟ajax数据加载新图片功能。

缺点:

1. 程序不是响应式,不能实时调整页面宽度;

2. 程序中当新增ajax模拟数据图片后,是将整个页面的所有图片都重新定位一次。

3. 程序是等所有图片加载完成后再读取图片的尺寸,实际中肯定不能这样做。

4. 实际项目中,应该由后台程序给出图片尺寸值,在js代码中直接使用图片的width属性。 

本程序思路:

html结构:

<body>
 <div id="container">
  <div class="box">
   <div class="box_img">
    <img src="img/1.jpg" />
   </div>
  </div>
  <div class="box">
   <div class="box_img">
    <img src="img/2.jpg" />
   </div>
  </div>
  ...
 </div>
</body>

一、初始化布局

1. 设置#container为position:relative;

2. 设置.box为float:left;

3. 网页加载后对所有图片进行定位;

3.1 图片宽度是固定的,计算出当前页面每行能容纳的图片数num,并得出#container的宽度,然后设置页面居中;

3.2 循环遍历所有图片,前num个图片默认float布局作为第一行,并存入数组BoxHeightArr = [];

3.3 第一行布局完成后,排布下一个图片,并更新BoxHeightArr[]:

3.3.1 将下一个图片放到第一行最矮图片的下方(用position:absolute定位),也就是BoxHeightArr[]中高度最小的那一列,记录下列数的索引值:minIndex;

3.3.2 更新BoxHeightArr[]中最小的那个值(BoxHeightArr[minIndex]+当前图片的高度);

3.4 重复循环3.3步骤,直到所有图片都排布完成

二、实时监测滚动高度,是否要加载新数据

1.初始化完成后得到最后一个图片距离顶部的高度: lastContentHeight

2.用window.onscroll = function(){...}

实时监测当前页面的滚动高度为:scrollTop

实时监测当前页面视窗高度为:pageHeight

3. 当页面监测到:lastContentHeight < scrollTop + pageHeight 时,用ajax获取新增图片的json数据。

三、页面底部新增内容

1. 用一个循环,先创建一个新的图片容器,添加到底部,然后将json数据中相应的图片数据如路径等信息写入该容器完成添加图片。

2. 所有新增图片添加完成后,对整个页面的所有图片及布局重新执行步骤一的初始化操作。

 项目文件夹:

纯js实现瀑布流布局及ajax动态新增数据

index.html: 预先置入部分图片数据

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <link rel="stylesheet" type="text/css" href="css/style.css"/>
 <script src="js/app.js"></script>
 <title>JavaScript瀑布流</title>
 </head>
 <body>
 <div id="container">
  <div class="box">
  <div class="box_img">
   <img src="img/1.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/2.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/3.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/4.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/5.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/6.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/7.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/8.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/9.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/10.jpg"/>
  </div>
  </div>
  
  <div class="box">
  <div class="box_img">
   <img src="img/1.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/2.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/3.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/4.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/5.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/6.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/7.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/8.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/9.jpg"/>
  </div>
  </div>
 
  <div class="box">
  <div class="box_img">
   <img src="img/10.jpg"/>
  </div>
  </div>
  
  <div class="box">
  <div class="box_img">
   <img src="img/1.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/2.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/3.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/4.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/5.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/6.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/7.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/8.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/9.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/9.jpg"/>
  </div>
  </div>
  <div class="box">
  <div class="box_img">
   <img src="img/10.jpg"/>
  </div>
  </div>
 </div>
 </body>
</html>

style.css:

*{
 margin: 0;
 padding: 0;
}
#container{
 position: relative;
}
.box{
 padding: 5px;
 float: left;
}
.box_img{
 padding: 5px;
 border: 1px solid #ccc;
 box-shadow: 0 0 5px #ccc;
 border-radius: 5px;
}
.box_img img{
 width: 150px;
 height: auto;
}

app.js:

window.onload = function(){
 imgLocation("container", "box");
 //ajax模拟数据
 var imgData = {"data":[{"src":"2.jpg"},{"src":"3.jpg"},{"src":"4.jpg"},{"src":"5.jpg"},{"src":"6.jpg"},{"src":"8.jpg"},{"src":"2.jpg"},{"src":"3.jpg"},{"src":"4.jpg"},{"src":"5.jpg"},{"src":"6.jpg"},{"src":"8.jpg"}]}
 
 window.onscroll = function(){
 if(checkFlag()){ //判断是否到底部要加载新的数据
  var cparent = document.getElementById("container");
  //把ajax数据加载进页面
  for(var i=0; i<imgData.data.length; i++){
  var ccontent = document.createElement("div");
  ccontent.className="box";
  cparent.appendChild(ccontent);
  var boximg = document.createElement("div");
  boximg.className = "box_img";
  ccontent.appendChild(boximg);
  var img = document.createElement("img");
  img.src = "img/"+imgData.data[i].src;
  boximg.appendChild(img);
  }
  //把所有图片数据重新定位一次
  imgLocation("container", "box");
 }
 }
};

function checkFlag(){
 var cparent = document.getElementById("container");
 var ccontent = getChildElement(cparent, "box");
 
 //得到最后一张图距顶部的高度,滚动高度,窗口高度
 var lastContentHeight = ccontent[ccontent.length-1].offsetTop;
 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
 var pageHeight = document.documentElement.clientHeight || document.body.clientHeight;
 console.log(lastContentHeight+":"+scrollTop+":"+pageHeight);
 
 if(lastContentHeight < scrollTop + pageHeight){
 return true;
 }
}

function imgLocation(parent, content){
 //将parent下所有的content全部取出
 var cparent = document.getElementById(parent);
 var ccontent = getChildElement(cparent, content);
 //根据当前浏览器窗口的宽度,确定每行图片数并固定,居中
 var imgWidth = ccontent[0].offsetWidth; //offsetWidth = width + padding + border
 var num = Math.floor(document.documentElement.clientWidth / imgWidth);
 cparent.style.cssText = "width:"+imgWidth*num+"px;margin:0 auto";
 //alert("pause");
 //设置一个数组,用来承载第一行的图片信息
 var BoxHeightArr = [];
 for(var i=0; i<ccontent.length; i++){
 if(i<num){
  //第一行的图片的高度记录下来
  BoxHeightArr[i] = ccontent[i].offsetHeight;
  //当ajax数据加载后,程序是将所有图片重新定位,所以第一行的图片要清除position:absolute
  ccontent[i].style.position = "static";
 }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";
  
  //图片放好位置后更新“第一行图片信息的最小高度”,
  //然后利用for循环重复这个动作到结束
  BoxHeightArr[minIndex] = BoxHeightArr[minIndex] + ccontent[i].offsetHeight;
 }
 }
;}

//获取第一行图片高度最小的索引值
function getminheightLocation(BoxHeightArr, minHeight){
 for(var i in BoxHeightArr){
 if(BoxHeightArr[i] == minHeight){
  return i;
 }
 }
}

//获取所有box
function getChildElement(parent, content){
 contentArr = parent.getElementsByClassName(content);
 return contentArr;
}

效果图:

纯js实现瀑布流布局及ajax动态新增数据

以上就是本文的全部内容,希望对大家学习javascript程序设计有所帮助。

Javascript 相关文章推荐
JS 密码强度验证(兼容IE,火狐,谷歌)
Mar 15 Javascript
体验js中splice()的强大(插入、删除或替换数组的元素)
Jan 16 Javascript
固定网页背景图同时保持图片比例的思路代码
Aug 15 Javascript
快速查找数组中的某个元素并返回下标示例
Sep 03 Javascript
Vuejs第九篇之组件作用域及props数据传递实例详解
Sep 05 Javascript
JS中使用mailto实现将用户在网页中输入的内容传递到本地邮件客户端
Oct 08 Javascript
jquery操作checkbox火狐下第二次无法勾选的解决方法
Oct 10 Javascript
微信小程序如何获取用户手机号
Jan 26 Javascript
AngularJS 事件发布机制
Aug 28 Javascript
JS实现简单tab选项卡切换
Oct 25 Javascript
vue中template的三种写法示例
Oct 21 Javascript
Vue全局事件总线你了解吗
Feb 24 Vue.js
原生JavaScript实现Ajax的方法
Apr 07 #Javascript
JavaScript数据推送Comet技术详解
Apr 07 #Javascript
js实现商品抛物线加入购物车特效
Nov 18 #Javascript
js类式继承与原型式继承详解
Apr 07 #Javascript
javascript原型继承工作原理和实例详解
Apr 07 #Javascript
浅析JS原型继承与类的继承
Apr 07 #Javascript
AngularJs 弹出模态框(model)
Apr 07 #Javascript
You might like
一个简洁实用的PHP缓存类完整实例
2014/07/26 PHP
jquery获取多个checkbox的值异步提交给php的方法
2015/06/24 PHP
显示、隐藏密码
2006/07/01 Javascript
javascript检测浏览器flash版本的实现代码
2011/12/06 Javascript
Jquery实现点击切换图片并隐藏显示内容(2种方法实现)
2013/04/11 Javascript
jquery内置验证(validate)使用方法示例(表单验证)
2013/12/04 Javascript
兼容最新firefox、chrome和IE的javascript图片预览实现代码
2014/08/08 Javascript
分享20款美化网站的 jQuery Lightbox 灯箱插件
2014/10/10 Javascript
js实现iframe自动自适应高度的方法
2015/02/17 Javascript
jquery实现从数组移除指定的值
2015/06/24 Javascript
纯js代码实现未知宽高的元素在指定元素中垂直水平居中显示
2015/09/12 Javascript
JS实现兼容性好,带缓冲的动感网页右键菜单效果
2015/09/18 Javascript
AngularJS实现表单手动验证和表单自动验证
2015/12/09 Javascript
理解javascript中的MVC模式
2016/01/28 Javascript
js拖拽的原型声明和用法总结
2016/04/04 Javascript
浅谈JS之iframe中的窗口
2016/09/13 Javascript
JS实现留言板功能
2017/06/17 Javascript
vuex2中使用mapGetters/mapActions报错的解决方法
2018/10/20 Javascript
微信小程序判断用户是否需要再次授权获取个人信息
2019/07/18 Javascript
Python生成随机密码
2015/03/10 Python
Django中对数据查询结果进行排序的方法
2015/07/17 Python
Python实现多线程抓取妹子图
2015/08/08 Python
Python+Django搭建自己的blog网站
2018/03/13 Python
Python numpy 点数组去重的实例
2018/04/18 Python
python3利用Socket实现通信的方法示例
2019/05/06 Python
详解Python图像处理库Pillow常用使用方法
2019/09/02 Python
python对验证码降噪的实现示例代码
2019/11/12 Python
python列表删除和多重循环退出原理详解
2020/03/26 Python
pyinstaller将含有多个py文件的python程序做成exe
2020/04/29 Python
android面试问题与答案
2016/12/27 面试题
教师工作决心书
2015/02/04 职场文书
2015年世界无烟日演讲稿
2015/03/18 职场文书
2015年国培研修感言
2015/08/01 职场文书
PyCharm 安装与使用配置教程(windows,mac通用)
2021/05/12 Python
如何在CSS中绘制曲线图形及展示动画
2021/05/24 HTML / CSS
Python+Matplotlib图像上指定坐标的位置添加文本标签与注释
2022/04/11 Python