1.瀑布流布局
思路:
要求:当图片宽度相同,高度不同时;如何做一面图片墙;每次图片加载到每列最低的位置;
1.图片的容器要相对定位,图片要相对容器绝对定位;
2.首先要求出当浏览器打开时或者改变大小时,浏览器的窗口能放入几张图片;即形成几列;
3.创建一个空数组来存放每列的高度值;
4.当有图片加载时根据数组里存放的高度大小;把图片放入高度最小的列;
5.当放入后更改放入后的高度;这样每次都可以把图片放入高度最低的列里形成好看的图片墙了。重点:
.content{
position:relative;
}
.item{
position: absolute;
transition:all 1s; /*渐变效果*/
}
function waterFull(){
var nodeWidth =$('.item').width();//元素宽度
var num =parseInt($('.content').width()/nodeWidth)//一排放多少个(取整)
var itemArr = [];//存放每列的高度;
for(var i=0; i<num;i++){//初始化
itemArr[i]=0;//目前每列高度为0;
}
$('.item').each(function(){//循环所有图片
var minValue = Math.min.apply(null,itemArr) //获取数组最小值(第一次就是数组的第一项0;)
var minIndex = itemArr.indexOf(minValue)//获取最小值的下标;
$(this).css({//通过改变top left ;放入图片的位置;
top:itemArr[minIndex],
left:$(this).outerWidth(true)*minIndex
})
itemArr[minIndex] += $(this).outerHeight(true);//更改添加后列的高度
})
}
- 看下效果:
- 优化:
1.在改变窗口大小时重新加载图片位置
2.当滚动时继续的加载图片;(写一个判断是否加载的函数checkScroll)
3.当滚动时发送ajax性后端要数据加载图片;(我这里是自己给的数据json模拟)
4.优化代码放入立即执行函数;
var WaterFull=(function(){
function init(){
waterFull()
$(window).resize(function(){//改变窗口大小
waterFull()
})
$(window).on('scroll',Scroll)//当窗口滚动时Mocks数据;
}
function waterFull(){
var nodeWidth =$('.item').width();//元素宽度
var num =parseInt($('.content').width()/nodeWidth)//一排放多少个(取整)
var itemArr = [];//存放每列的高度;
for(var i=0; i<num;i++){//初始化
itemArr[i]=0;//目前每列高度为0;
}
$('.item').each(function(){//循环所有图片
var minValue = Math.min.apply(null,itemArr) //获取数组最小值(第一次就是数组的第一项0;)
var minIndex = itemArr.indexOf(minValue)//获取最小值的下标;
$(this).css({//通过改变top left ;放入图片的位置;
top:itemArr[minIndex],
left:$(this).outerWidth(true)*minIndex
})
itemArr[minIndex] += $(this).outerHeight(true);//更改添加后列的高度
})
}
function Scroll(){
var dataInt = {
'data':[{'src':'1.png'},{'src':'2.png'},{'src':'3.png'},{'src':'4.png'},{'src':'5.png'},{'src':'6.png'},{'src':'7.png'},
{'src':'8.png'},{'src':'9.png'},{'src':'10.png'},{'src':'11.png'},{'src':'12.png'},{'src':'13.png'},{'src':'14.png'}]
}
var isArrive= false;//防止多次滚动重复数据
if(checkScroll() && !isArrive){
var oParent = document.getElementsByClassName('content')[0];
for(var i =0;i<dataInt.data.length;i++){
isArrive=true;
var oDiv =document.createElement('div');//添加元素节点
oDiv.className ='item';
oDiv.innerHTML ='![](./img/'+dataInt.data[i].src+')'
oParent.appendChild(oDiv);
}
isArrive = false;
waterFull()
}
}
function checkScroll(){
var oParent = document.getElementsByClassName('content')[0];
var aDiv =oParent.getElementsByClassName('item');
var lastPinH=aDiv[aDiv.length-1].offsetTop+Math.floor(aDiv[aDiv.length-1].offsetHeight/2);
//创建【触发添加块框函数waterfall()】的高度:最后一个块框的距离网页顶部+自身高的一半(实现未滚到底就开始加载)
var scrollTop=$(window).scrollTop();//滚动高度
var winndowHeight=$(window).height(); //页面高度
return (lastPinH<scrollTop+winndowHeight)? true : false ; //到达指定高度后 返回true,触发waterfall()函数
}
return {
init:init
}
})()
WaterFull.init();
- 原生js代码
function waterFull(){
var Oparent = document.getElementById('main');
var aPin =Oparent.getElementsByClassName('pin')//获取存储块pin的数组;
var num =Math.floor(document.documentElement.clientWidth/aPin[0].offsetWidth)//获取窗口每行能容纳的个数
var pinHArr=[];//用于存储 每列中的所有块框相加的高度
for(var i =0 ; i<num;i++){
pinHArr[i]=0;
}
for(var i =0 ; i<aPin.length;i++){
//获取PinHArr的最小值;
var minValue =Math.min.apply(null,pinHArr);
//获取pinHArr最小值得索引;
var minIndex = pinHArr.indexOf(minValue);
aPin[i].style.top=minValue+'px';//用定位改变其top值
aPin[i].style.left=aPin[minIndex].offsetWidth*minIndex+'px';//用定位改变其left值
pinHArr[minIndex] += aPin[i].offsetHeight;//更改添加后列的高度
}
}
- css瀑布流效果:
- 关于css瀑布流:
方法有许多种,优缺点都有,但是本人建议用js或者jquery;因为毕竟是要向后端mock数据所以css布局不建议使用;就给出css3方法其中一种代码
<style>
*{padding:0;margin:0;}
.clearfix:after,
.clearfix:before {
content: " ";
display: table;
}
.clearfix:after {
clear: both;
}
.main {
position: relative;
-webkit-column-width: 222px;
-moz-column-width: 222px;
/*column-width 属性规定列的宽度。*/
-webkit-column-gap: 5px;
/*column-gap 属性规定列之间的间隔。*/
-moz-column-gap: 5px;
}
.box {
float: left;
padding: 15px 0 0 15px;
transition: all 1s;
}
.box .pic {
width: 200px;
height: auto;
padding: 10px;
border-radius: 5px;
box-shadow: 0 0 5px #cccccc;
}
.box .pic img {
display: block;
width: 100%;
}
-
css3瀑布流布局:
我们将要用到的是CSS3新加的column属性,通过指定容器的列个数column-count,列间距column-gap,列中间的边框(间隔边线)column-rule,列宽度column-width实现。优点:
1. 直接用CSS定义,方便快捷,是最好不过了;
2. 扩展方便。缺点:
1. 目前仍有部分浏览器不支持CSS3;
2.CSS3这种方式的数据排列是从上到下排列到一定高度后,再把剩余元素依次添加到下一列;
2.木桶布局
- 思路:
1.当图片加载进来时,初始化new的image对象,给图片定一个高度;获取等比例下的宽度;
2.把图片的宽高放入一个空数组,通过循环数组获取图片的总宽度;
3.拿获取的总宽度跟容器宽度相比较,如果总宽度大于容器宽度,那就拿出最后一个图片的宽度,直到总宽度小于容器的宽度。然后拉伸容器里的图片让,图片填充这个容器的宽度(获取容器里现在的最后高度)
4.再把数组清空,放入刚才被拿出的最后放不下那一项(重置数组总宽度)
5.写一个函数渲染每排图片(把新高度传入进去)。
- 难点
1.当图片加载进来时,初始化new的image对象,给图片定一个高度;获取等比例下的宽度;
loadImg:function(){//构建url就是一个接口;也可以是ajax;
var _this = this //保存作用于的this
var imgUrls = this.getImgUrls(40);//如果是ajax是不可能根据图片地址获取他的宽高的
$.each(imgUrls,function(idx,url){//所以循环这个数组,
var img = new Image();//创建一个图片对象;
img.src =url;
img.onload =function(){
var imgInfo ={
target:$(img),//哪一张图片
width:200*(img.width/img.height),// x/200=img.width/img.height
height:200//高度设为200;
}
_this.render(imgInfo);
}
})
},
2.把图片的宽高放入一个空数组,通过循环数组获取图片的总宽度;
render: function(imgInfo){
var clientWidth = this.$ct.width();
var rowWidth = 0;
var newRowHeight = 0;
var lastImgInfo = imgInfo;
this.rowList.push(imgInfo);
for(var i=0; i< this.rowList.length; i++){
rowWidth = rowWidth + this.rowList[i].width;
}
3.那获取的总宽度跟容器宽度相比较,如果总宽度大于容器宽度,那就拿出最后一个图片的宽度,直到总宽度小于容器的宽度。然后拉伸容器里的图片让,图片填充这个容器的宽度(获取容器里现在的最后高度)
if(rowWidth > clientWidth){
this.rowList.pop();
rowWidth = rowWidth-lastImgInfo.width//目前每行的宽度;
newRowHeight = clientWidth*200/rowWidth;
// rowWidth/200 == clientWidth/ X
4.再把数组清空,放入刚才被拿出的最后放不下那一项(重置数组总宽度)
this.rowList = [];
this.rowList.push(imgInfo);
this.layout(newRowHeight);
5.写一个函数渲染每排图片(把新高度传入进去)
layout: function(newRowHeight){
console.log('createRow');
var $rowCt = $('<div class="img-row"></div>');
$.each(this.rowList, function(idx, imgInfo){
var $imgCt = $('<div class="img-box"></div>'),
$img = $(imgInfo.target);
$img.height(newRowHeight);
$imgCt.append($img);
$rowCt.append($imgCt);
});
this.$ct.append($rowCt);
- 效果:
3.等高布局
思路:等高布局有几种不同的方法如定位,但目前为止我认为浏览器兼容最好最简便的应该是padding补偿法。首先把列的padding-bottom设为一个足够大的值,再把列的margin-bottom设一个与前面的padding-bottom的正值相抵消的负值,父容器设置超出隐藏,这样子父容器的高度就还是它里面的列没有设定padding-bottom时的高度,当它里面的任一列高度增加了,则父容器的高度被撑到它里面最高那列的高度,其他比这列矮的列则会用它们的padding-bottom来补偿这部分高度差。因为背景是可以用在padding占用的空间里的,而且边框也是跟随padding变化的,所以就成功的完成了一个障眼法。
重点:
.wrap{
overflow: hidden;//父容器设置超出隐藏,这样子父容器的高度就还是它里面的列没有设定padding-bottom时的高度
}
.left{
float: left;
padding-bottom: 10000px;
margin-bottom: -10000px;
}
.right{
float: right;
padding-bottom: 10000px;
margin-bottom: -10000px;
}
- 看下效果:
- 代码
<style>
.wrap{
width:100%;
background:#ccc;
overflow: hidden;
min-width: 600px;
}
.left{
width:300px;
float: left;
padding-bottom: 10000px;
margin-bottom: -10000px;
background: red;
text-align: center;
border: 1px saddlebrown solid;
}
.right{
width:300px;
float: right;
padding-bottom: 10000px;
margin-bottom: -10000px;
background:green;
text-align: center;
border: 1px saddlebrown solid;
}
h2{
padding: 10px;
}
</style>
</head>
<body>
<div class="wrap">
<div class="left">
![](./img/1.png)
</div>
<div class="right">
![](./img/2.png)
</div>
</div>
<button class="btn1">左侧栏增加高度</button>
<button class="btn2">右侧栏增加高度</button>
<script src="jquery-3.2.0.min.js"></script>
<script>
$('.btn1').on('click',function(){
$('.left').append('![](./img/1.png)')
})
$('.btn2').on('click',function(){
$('.right').append('![](./img/2.png)')
})
</script>
</body>
4. 圣杯布局
思路:
圣杯布局解决的问题是两边顶宽,中间自适应的三栏布局,中间栏要在放在文档流前面以优先渲染。圣杯布局的三栏全部float浮动,但左右两栏加上负margin让其跟中间栏div并排,以形成三栏布局。解决”中间栏div内容不被遮挡“问题的思路:圣杯布局,为了中间div内容不被遮挡,将中间div设置了左右padding-left和padding-right后,将左右两个div用相对布局position: relative并分别配合right和left属性,以便左右两栏div移动后不遮挡中间div。重点:
div{
float:left;
}
.wrap
{
padding-right: 100px;//空出左右位置给左右两栏;
padding-left:100px
}
.left
{
margin-left: -100%;//左边栏与中间拦并排;
position: relative;
left: -100px;//左边的div宽度大小;
}
.right
{
margin-left: -100px;//右边栏与中间拦并排;大小为右边栏宽度;
position: relative;
left: 100px;//左边的div宽度大小;
}
- 看下效果:
- 代码
<style>
.wrap{
border: 1px saddlebrown solid;
padding-left:100px;
padding-right: 100px;
min-width: 600px;
}
.clear:after{
content:'';
display: block;
clear:both;
}
.main{
width:100%;
height: 200px;
float:left;
background:red;
}
.left{
float: left;
width:100px;
height: 100px;
background:green;
margin-left: -100%;
position: relative;
left: -100px;
}
.right
{
float: left;
width: 100px;
height: 100px;
background: pink;
margin-left: -100px;
position: relative;
left: 100px;
}
</style>
</head>
<body>
<div class="wrap clear">
<div class="main"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
5.双飞翼布局:
思路:
圣杯布局和双飞翼布局解决的问题是一样的,就是两边顶宽,中间自适应的三栏布局,中间栏要在放在文档流前面以优先渲染。圣杯布局和双飞翼布局解决问题的方案在前一半是相同的,也就是三栏全部float浮动,但左右两栏加上负margin让其跟中间栏div并排,以形成三栏布局。不同在于解决”中间栏div内容不被遮挡“问题的思路不一样;双飞翼布局:为了中间div内容不被遮挡,直接在中间div内部创建子div用于放置内容,在该子div里用margin-left和margin-right为左右两栏div留出位置。重点:
.main
{
width: 100%;
float: left;
}
.main .mainer//在中间div内部创建子div用于放置内容,在该子div里用margin-left和margin-right为左右两栏div留出位置
{
margin-left: 120px;
margin-right: 120px;
}
.left
{
float: left;
margin-left: -100%; //左边栏与中间拦并排;
}
.right
{
float: left;
margin-left: -100px; //右边栏与中间拦并排
}
- 看下效果:
- 代码:
.wrap
{
border: 1px saddlebrown solid;
min-width: 600px;
}
.clear:after
{
content: "";
display: block;
clear: both;
}
.main
{
width: 100%;
height: 200px;
float: left;
}
.main .mainer
{
background: black;
height: 200px;
margin-left: 120px;
margin-right: 120px;
}
.left
{
width:100px;
height: 100px;
background:green;
float: left;
margin-left: -100%;
}
.right
{
width: 100px;
height: 100px;
background: pink;
float: left;
margin-left: -100px;
}
</style>
</head>
<body>
<div class="wrap clear">
<div class="main">
<div class="mainer"></div>
</div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
- 圣杯双飞翼的区别:
圣杯布局和双飞翼布局解决的问题是一样的,就是两边顶宽,中间自适应的三栏布局,中间栏要在放在文档流前面以优先渲染。圣杯布局和双飞翼布局解决问题的方案在前一半是相同的,也就是三栏全部float浮动,但左右两栏加上负margin让其跟中间栏div并排,以形成三栏布局。不同在于解决”中间栏div内容不被遮挡“问题的思路不一样:圣杯布局,为了中间div内容不被遮挡,将中间div设置了左右padding-left和padding-right后,将左右两个div用相对布局position: relative并分别配合right和left属性,以便左右两栏div移动后不遮挡中间div。双飞翼布局,为了中间div内容不被遮挡,直接在中间div内部创建子div用于放置内容,在该子div里用margin-left和margin-right为左右两栏div留出位置。
6. Flex布局:
Flex布局也是很常用的布局方法可以点击链接去了解下Flex布局方法用法.
Flex布局
7.最后看下jquery实战-无限加载-jsonp-瀑布流
希望对给位朋友有所帮助~~~
版权归饥人谷__楠柒所有,如要转载请请注明出处~