**瀑布流概念**:
又称瀑布流式布局,是比较流行的一种网站页面布局方式。
视觉表现为参差不齐的多栏布局,最早采用此布局的是网站是Pinterest,后逐渐在国内流行。
**瀑布流原理**:
页面容器内的多个高度不固定的div之间按照一定的间隔参差不齐的无序浮动,
鼠标滚动时不断在容器内的尾部加载数据,且自动加载到空缺位置,不断循环。
** 优点:**
1.有效降低了界面复杂度,节省了空间:
不再需要臃肿复杂的页面导航链接或者按钮了;
2.在触屏设备上交互方式有更好的用户体验,
通过向上滑动进行页面滚动和数据加载,对操作的精准程度要求远远低于点击按钮或者链接;
3.更高的参与度,使用户能更好的专注于浏览而不是操作;
** 缺点:**
1.无限滚动只适用与特定类型产品中的某一类型,如某类微博信息,购物网站的某类商品,而不适用与一般的门户网站,使用需斟酌;
2.需要打造额外的js库来保证页面数据的加载和排列,而这在一定意义上增加了在网页的性能和设备兼容等方面的问题;
** js核心思路:**
1.编写方法:获取容器内所有外层元素,存入数组;
2.编写方法:计算容器内一行可以承载多少个元素,方法:容器宽度/元素宽度,四舍五入向下取整;
3.编写方法:把每一行中所有元素的高度值存入数组;
4.编写方法:在高度值数组中找到最小高度值;
5.编写方法:把第二行第一个元素定位到上一行所有元素中高度最低的元素下面,即设置该元素的top,left,position属性;
6.编写方法:重置当前高度值数组中的最小值;
7.编写方法:从第二行第一个元素开始,遍历每个元素,用上述方法重新定位每个元素的位置,把该事件绑定到页面;
8.编写方法:监听鼠标事件,当前容器内最下面一个元素的offsetTop<浏览器可视高度+已滚动高度时,加载下一页数据;
9.加载完之后,用上述方法重新定位新加载元素的位置;
代码效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*{
margin: 0px;
padding: 0px;
}
#container{
position: relative;
}
.box{
padding: 7px;
float: left;
margin: 0px auto;
}
.box_img{
padding: 5px;
border: 1px solid #DCDCDC;
box-shadow: 0 0 5px #ccc;
border-radius: 5px;
}
.box_img img{
width: 230px;
}
</style>
</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/3.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/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>
</body>
</html>
<script>
window.onload=function(){
imgLocation("container","box");
var imgData={"data":[{"src":"1.jpg"},{"src":"2.jpg"},{"src":"3.jpg"},{"src":"3.jpg"},{"src":"4.jpg"},{"src":"5.jpg"},{"src":"6.jpg"},{"src":"2.jpg"},{"src":"3.jpg"},{"src":"3.jpg"},{"src":"4.jpg"},{"src":"5.jpg"}]}
window.onscroll=function(){
// console.log(document.documentElement.scrollTop);
if(checkFlag()){
var cparent=document.getElementById("container");
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);
//另外一种方法在div后边追加内容,不覆盖原有内容
// var content="<div class='box'><div class='box_img'><img src='img/"+imgData.data[i].src+"'/></div></div>";
// cparent.innerHTML+=content;
}
imgLocation("container","box");
}
}
}
function checkFlag(){
var cparent=document.getElementById("container");
var ccontent=getChildElement(cparent,"box");//图片的所有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){
var cparent=document.getElementById(parent);
var ccontent=getChildElement(cparent,content);//图片的所有box数
var imgWidth=ccontent[0].offsetWidth;//图片宽度
var num=Math.floor(document.documentElement.clientWidth/imgWidth);//一行放图片个数
cparent.style.cssText="width:"+imgWidth*num+"px;margin:0px auto";//container的宽度
var boxHeightArr=[];//每一列box高度
for(var i=0;i<ccontent.length;i++){
if(i<num){
boxHeightArr[i]=ccontent[i].offsetHeight;
}else{
var minHeight=Math.min.apply(null,boxHeightArr);//最小高度
var minIndex = getMinheightLocation(boxHeightArr,minHeight);//得到最小高度下标
// console.log(minHeight+","+minIndex);
ccontent[i].style.position="absolute";
ccontent[i].style.top=minHeight+"px";//距离顶部高度
ccontent[i].style.left=ccontent[minIndex].offsetLeft+"px";//距离左边长度
boxHeightArr[minIndex]+=ccontent[i].offsetHeight;
// console.log(ccontent[i].offsetHeight+","+ccontent[i].height);//ccontent[i].height=undefined
}
}
}
function getMinheightLocation(boxHeightArr,minHeight){
for(var i in boxHeightArr){
if(boxHeightArr[i]==minHeight){
return i
}
}
}
function getChildElement(parent,content){
//将parent下有content的全部取出
var contentArr=[];
var allContent=parent.getElementsByTagName("*");
for(i=0;i<allContent.length;i++){
if(allContent[i].className=="box"){
contentArr.push(allContent[i]);
}
}
return contentArr;
}
</script>
兼容性
1 点击300ms 使用fastclick
2 移动端1px 在ios中使用0.5px
3 js中获取浏览器高度,获取scrollTOP等属性需要兼容
4 H5 的audio在ios上autoplay不会自动播放 一般使用进入页面后,使用js控制播放
5 在html上加overflow:hidden属性的时候,好多移动端浏览器都不支持
要实现超出范围隐藏,滚动条不显示,一般使用js获取高度来动态设置html高度
6 ios系统中在移动浏览器的页面中给按钮加JS事件,其按钮必须是原生HTML按钮或者由<a>标签自定义构成。
原来在IOS系统中,浏览器只支持给原生HTML按钮或<a>标签加JS事件
7 你用js 生成的一个按钮 <div class="btn">按钮</div>
在ios上直接$("#btn").click是不能加点击事件的,必须使用事件委托
8 h5页面 当输入框在最底部,点击软键盘后输入框会被遮挡。定时器或者修改为固定定位
setTimeout(function(){
document.body.scrollTop = document.body.scrollHeight;
},300);
var oHeight = $(document).height(); //浏览器当前的高度
$(window).resize(function(){
if($(document).height() < oHeight){
}else{
$("#footer").css("position","absolute");
}