web学习-瀑布流布局(1)
来源:互联网 发布:js中top对象 编辑:程序博客网 时间:2024/04/30 01:54
在mooc网上学习了瀑布流布局的实现,自己就记录了一下,留作一个笔记^.^
瀑布流样式
在页面中有大大小小的box,box的宽度相同,高度不同,竖直排列成N列,当滚动条向下面滚动的时候自动加载box,形成瀑布流
基本结构
(1)html结构:
<body><div id="warp"> <div class='box'><div class='pic'><img></div><div> </div></body>
(2)css样式:
* { margin: 0; padding: 0;}warp{ margin: 0 auto;}.box { padding: 15px 0 0 15px; float: left; position: absolute;}.pic { padding: 10px; border: 1px solid #ccc; border-right: 5px; box-shadow: 0 0 5px #ccc;}.pic img { width: 165px; height: auto;}
瀑布流实现原理
采用js来实现
- 在Css中已经把box都设置成绝对定位,通过box的top,left值来计算出一个盒子该出现的位置.
- 在js中维护一个数组,这个数组的长度是瀑布流的列数,数组的值储存键值对应的列的高度,arr[1]指的是第一列的总高度,以此类推.
- 新的box应该插入在当前页面所有列中最’短’的列,在arr中值最小既是最小的列,得到该最小值对应的索引就是最’短’ 的列.
滚动加载实现的方式:
- 在所有的box中找到排列最后的那个box(靠下面的box都行)
- 计算1中box的offsetTop(距离文档顶部的距离)+offsetHeight(box的高度)/2
- 计算屏幕的高度,doucment.documentElement.clientHeight
- 计算文档距离window的高度,也就是滚动条的高度:document.documentElement.scrollTop
- 如果2值<=(4值+3值)的话,那么就可以判断屏幕已经显示到底部了,要加载新的box了
数据请求的时刻:
- 页面加载完毕的时候,ajax.send(‘action=first’)
- 滚动条滚动到底部的时候ajax.send(‘action=next’)
代码片段
(1)ajax请求的代码
/** * [ajax description] ajax的处理 * @param {[string]} url [description] ajax post的地址 * @param {string} content [description] ajax send * @return {[string]} json [description] json */ function ajax(url,content,callback){ var ajax = new XMLHttpRequest(); ajax.open('post',url); ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8"); ajax.send(content); ajax.onreadystatechange = function(){ if(ajax.readyState===4 && ajax.status ===200){ callback(ajax.responseText); console.log(ajax.responseText); }else{ return 'error'; } } }
(2)添加盒子的代码
/** * [Boxs description] 在页面中插入盒子 * @param {[document.node]} parent [description] 放入盒子的父节点 * @param {[array]} pics [description] 储存图片地址的数组 * @param {[int]} total [description] 盒子的数目 * @param {Function} callback(img,pic,box) [description] 回调函数(图片,图片父节点div,box.div) */ function Boxs(pics,total){ this.total = total || 1; this.pictures = pics || null; this.addBoxs = function(parent,callback){ for(var i = 0;i<total;i++){ var box = document.createElement('div'); box.className = 'box'; var pic = document.createElement('div'); pic.className = 'pic'; var img = document.createElement('img'); img.src = pics[i]; pic.appendChild(img); box.appendChild(pic); parent.appendChild(box); img.onload = callback(img,pic,box); } } }
(3)一些初始化(后台地址,维护的数组,初始化列的宽度)
const url = './ajaxTest.php'; var boxWidthArr = []; var boxWidth = 0 ;
(4)在window.onload中进行ajax请求,并且计算box的位置
window.onload = function(){ ajax(url,'action=first',function(response){ var json = JSON.parse(response); boxWidth = json.width; var boxRowNum = Math.floor((document.getElementsByTagName('body')[0].offsetWidth) / boxWidth); for(var i=0;i<boxRowNum;i++){boxWidthArr[i] = 0;}; var box = new Boxs(json.files,json.files.length); box.addBoxs(document.getElementById('warp'),function(img,pic,box){ // box添加以及计算 var minH = Math.min.apply(null,boxWidthArr);//计算储存列高度最小的那个高度 var minIndex = 0; while(minIndex < boxWidthArr.length){if(boxWidthArr[minIndex] == minH) break;minIndex++;}//找到最小值的那个键值 box.style.top = minH + 15 + 'px';// top的计算是用最小值加上15px box.style.left = minIndex*boxWidth + 'px';//left的值是最小值的那个索引乘上盒子的宽度 boxWidthArr[minIndex] += box.offsetHeight;//每次添加完box要更新所在列的高度对应数组中的值 }); })
(5)检查是否要加载图片了,就是滚动条是否滚动到底部了
function checkScrollSlider(){ var lasbox = document.querySelectorAll('.box')[document.querySelectorAll('.box').length-1]; var lastBoxDis = lasbox.offsetTop + Math.floor(lasbox.offsetHeight / 2); var documentH = document.documentElement.clientHeight; var scrollTop = document.documentElement.scrollTop; return ((lastBoxDis <= scrollTop + documentH)?true:false); };
(6)在window.onscroll中检查是否要加载图片了,没当滚动条动的时候就检查一次
if(checkScrollSlider()){ ajax(url,'action=next',function(response){ var json = JSON.parse(response); var box = new Boxs(json.files,json.files.length); box.addBoxs(document.getElementById('warp'),function(img,pic,box){ // box添加以及计算 var minH = Math.min.apply(null,boxWidthArr); var minIndex = 0; while(minIndex < boxWidthArr.length){if(boxWidthArr[minIndex] == minH) break;minIndex++;} box.style.top = minH + 15 + 'px'; box.style.left = minIndex*boxWidth + 'px'; boxWidthArr[minIndex] += box.offsetHeight; }); }) } }
最终的效果:
学习总结:
(1)碰到的第一个问题就是img加载的问题.我当时是想是加一张图片就计算它的位置,还是等所有图片都加载完成了在整理他们的位置.后来决定加一张图片就计算位置.当时不知道img有个onload事件,每次都是在设置img的src之后就计算位置,每次计算的都是错误的(当时img根本没有加载完)….坑了,折腾啦好长时间
(2)第二个问题就是那个ajax.send(),它能发送一个http的请求头.但是一开始不知道,不知道怎么让后台代码区分是一开始加载的,还是后面滚动条触发加载的
(3)不能把代码写的很紧密.就采用回调的方式,也不知道这个方式是好是坏
1 0
- web学习-瀑布流布局(1)
- web学习-瀑布流布局(2)
- web之瀑布流布局
- jQuery学习实例:瀑布流布局
- 瀑布流布局浅析
- 瀑布流布局
- 瀑布流布局浅析
- 瀑布流布局浅析
- 瀑布流布局浅析
- js瀑布流布局
- 瀑布流布局浅析
- 瀑布流布局浅析
- 瀑布流布局浅析
- 瀑布流布局浅析
- 瀑布流布局浅析
- 图片瀑布流布局
- Android 瀑布流布局
- 瀑布流布局代码
- C++学习-多继承和虚基类(11) http://blog.csdn.net/gzshun/article/details/7300458
- 第九周项目3 稀疏矩阵的三元组表示的应用2
- linux 库文件查找及其可执行文件查找定位
- 支部党员大会讨论接收预备党员的主要程序
- 海康大华PC客户端集成播放器
- web学习-瀑布流布局(1)
- hdoj2026 首字母变大写
- [黑马IOS自学第十三篇]@protocol协议学习
- target runtime Apache Tomcat v6.0 is not defind 错误解决
- web应用安全防御100技
- JAVA设计模式初探之适配器模式
- python: 通过脚本实现重要文件的备份
- Unity leapmotion开发实录(4)
- OCUnit和GHUnit和OCMock