纯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 相关文章推荐
基于jquery实现的表格分页实现代码
Jun 21 Javascript
jquery预览图片实现鼠标放上去显示实际大小
Jan 16 Javascript
ECMAScript6的新特性箭头函数(Arrow Function)详细介绍
Jun 07 Javascript
JavaScript Promise启示录
Aug 12 Javascript
JavaScript实现查找字符串中第一个不重复的字符
Dec 29 Javascript
JS函数多个参数默认值指定方法分析
Nov 28 Javascript
angularjs实现简单的购物车功能
Sep 21 Javascript
js实现把时间戳转换为yyyy-MM-dd hh:mm 格式(es6语法)
Dec 28 Javascript
解决eclipse中没有js代码提示的问题
Oct 10 Javascript
详解vue配置后台接口方式
Mar 29 Javascript
vue实现跳转接口push 转场动画示例
Nov 01 Javascript
详解Node.JS模块 process
Aug 31 Javascript
原生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
简单易用的计数器(数据库)
2006/10/09 PHP
php数组合并的二种方法
2014/03/21 PHP
javascript 点击整页变灰的效果(可做退出效果)。
2008/01/09 Javascript
非常有用的40款jQuery 插件推荐(系列二)
2011/12/25 Javascript
不用锚点也可以平滑滚动到页面的指定位置实现代码
2013/05/08 Javascript
JS返回上一页实例代码通过图片和按钮分别实现
2013/08/16 Javascript
JavaScript获取图片真实大小代码实例
2014/09/24 Javascript
nodejs中简单实现Javascript Promise机制的实例
2014/12/06 NodeJs
javascript进行四舍五入方法汇总
2014/12/16 Javascript
jQuery前端分页示例分享
2015/02/10 Javascript
AngularJS包括详解及示例代码
2016/08/17 Javascript
AngularJS国际化详解及示例代码
2016/08/18 Javascript
React教程之封装一个Portal可复用组件的方法
2018/01/02 Javascript
微信小程序页面生命周期详解
2018/01/31 Javascript
vue解决一个方法同时发送多个请求的问题
2018/09/25 Javascript
解决微信小程序中转换时间格式IOS不兼容的问题
2019/02/15 Javascript
JS写滑稽笑脸运动效果
2020/05/28 Javascript
[03:48]2014DOTA2 TI专访71DK夺冠不靠小组赛高排名
2014/07/11 DOTA
[01:05:30]VP vs TNC 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
Python列表(list)常用操作方法小结
2015/02/02 Python
举例讲解Python编程中对线程锁的使用
2016/07/12 Python
浅析Django中关于session的使用
2019/12/30 Python
python3 logging日志封装实例
2020/04/08 Python
CSS3实现精美横向滚动菜单按钮
2017/04/14 HTML / CSS
英国皇室御用百货:福南梅森(Fortnum & Mason)
2017/12/03 全球购物
世界排名第一的运动鞋市场:Flight Club
2020/01/03 全球购物
摩飞电器俄罗斯官方网站:Morphy Richards俄罗斯
2020/07/30 全球购物
简述安装Slackware Linux系统的过程
2012/01/12 面试题
PHP使用Redis队列执行定时任务实例讲解
2021/03/24 PHP
自我鉴定200字
2013/10/28 职场文书
信息学院毕业生自荐信范文
2014/03/04 职场文书
家长对老师的感言
2014/03/11 职场文书
项目合作意向书范本
2014/04/01 职场文书
Python实现Telnet自动连接检测密码的示例
2021/04/16 Python
解决Golang time.Parse和time.Format的时区问题
2021/04/29 Golang
详解apache编译安装httpd-2.4.54及三种风格的init程序特点和区别
2022/07/15 Servers