原生js瀑布流及其原理

瀑布流目前已经不在是很时尚的词了,不过知道他实现的原理和具体实现过程还是值得我们好好学习的。

 

瀑布流效果目前在大多数网站中可以见到,参差不齐的多栏布局格式,是瀑布流的特点。瀑布流可以通过jQuery插件结合css代码来实现。
        对于图片的展现,瀑布流的效果是高效而且独具吸引力的。瀑布流里延迟加载模式又避免了用户鼠标点击的翻页操作,瀑布流的主要特性便是错落有致,定宽而不定高的设计让页面区别于传统的矩阵式图片布局模式,巧妙的利用视觉层级,视线的任意流动又缓解了视觉疲劳。

几种实现方式
  随着越来越多设计师爱用这种布局,我们作为前端,要尽可能满足视觉/交互设计师的需求。所以,我们整理了下这种布局的几种实现方式,有三种:
1) 传统多列浮动。即 蘑菇街和哇哦 采用的方式,如下图所示:

  • 各列固定宽度,并且左浮动;
  • 一列中的数据块为一组,列中的每个数据块依次排列即可;
  • 更多数据加载时,需要分别插入到不同的列上;

优点:

  • 布局简单,应该说没啥特别的难点;
  • 不用明确知道数据块高度,当数据块中有图片时,就不需要指定图片高度。

缺点:

  • 列数固定,扩展不易,当浏览器窗口大小变化时,只能固定的x列,如果要添加一列,很难调整数据块的排列;
  • 滚动加载更多数据时,还要指定插入到第几列中,还是不方便。

 

那么下面我们就做一下这种布局的实现代码:

 

 

<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="utf-8">
		<title>Pinterest</title>
<style>
	*{margin:0; padding: 0;}
	ul,li{ list-style: none}
	.clearfix:before,.clearfix:after {content:"";display:table;}
	.clearfix:after {clear:both;}
	.clearfix {zoom:1; /* IE < 8 */clear:both;}
	.waterfall{width: 660px; height: auto; margin:20px auto;}
	.waterfall ul{ width:210px; margin:5px; float: left; }
</style>
<script type="text/javascript" src="ajax.js"></script>
<script>
/*
1,布局:浮动
2,数据添加
a,浮动布局的话,页面中(一竖排一个ul)有几个ul,css就很容易写直接浮动就好了,难点呢就是数据添加,数据要分别添加到4个ul中,要同时的。。

*/
/*
浮动布局
*/
window.οnlοad=function(){
		var aUl = document.getElementsByTagName("ul");
		var bBtn=true;
//滚动条事件,获取可视区的距离,和滚动条的距离。
		window.onscroll = function(){
			var veiwHeight = document.documentElement.clientHeight;
			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
			for(var i=0; i<aUl.length;i++){
				var aLi=aUl[i].getElementsByTagName("li");
				var lastLi = aLi[aLi.length-1];
				if(posTop(lastLi) < veiwHeight + scrollY && bBtn){
					bBtn=false;
					ajax("data.js",function(str){
						var json=eval("(" + str + ")");
						if(json.code){
							bBtn=true;
						}
						for(var i=0;i<json.list.length;i++){
							var list=json.list[i];
							for(var j=0;j<list.src.length;j++){
								var oLi =document.createElement("li");
								oLi.innerHTML="<img src="+list.src[j]+" /><p>"+list.title[j]+"</p>";
								aUl[i].appendChild(oLi);
							}
						}
					});
				}
			}
		};

//获取到屏幕的距离
		function posTop(obj){
			var top = 0;
			while(obj){
				top += obj.offsetTop;
				obj = obj.offsetParent;
			}
			return top;
		}

};
</script>

	</head>
	<body>
		<div class="waterfall">
			<ul>
				<li>
					<img src="images/1.jpg" />
					<p>1111111111</p>
				</li>
				<li>
					<img src="images/2.jpg" />
					<p>222222222222222</p>
				</li>
				<li>
					<img src="images/3.jpg" />
					<p>333333333333</p>
				</li>
				<li>
					<img src="images/3.jpg" />
					<p>333333333333</p>
				</li>
			</ul>
			<ul>
				<li>
					<img src="images/4.jpg" />
					<p>444444444444</p>
				</li>
				<li>
					<img src="images/5.jpg" />
					<p>55555555555555</p>
				</li>
				<li>
					<img src="images/6.jpg" />
					<p>66666666666</p>
				</li>

			</ul>
			<ul>
				<li>
					<img src="images/7.jpg">
					<p>77777777777777</p>
				</li>
				<li>
					<img src="images/8.jpg">
					<p>88888888888</p>
				</li>
				<li>
					<img src="images/9.jpg">
					<p>9999999999</p>
				</li>
			</ul>
		</div>
	</body>
</html>	
 

 

这个是绝对定位的方式来实现的,主要先要用js算好left和top值。做的是固定三列。代码待优化。

 

 

<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="utf-8">
		<title>Pinterest</title>

	</head>
	<style>
	*{margin:0; padding: 0;}
	ul,li{ list-style: none}
	.waterfall{width: 660px; height: auto; margin:20px auto; position: relative;}
      
      li{ position: absolute;}
</style>
<script type="text/javascript" src="ajax.js"></script>
<script>
/*
1,布局:定位  
2,数据添加
b,定位布局,把所有的li放到一个ul里面,然后通过js给他们定位,这时候js要求就比较高,而数据添加就简单了直接把数据返回回来然后添加到ul当中就好了。这样写的一个缺点呢就是一定要获取到li的高度才可以,根据高度来算top值和left值
*/
/*
绝对定位布局
*/
window.οnlοad=function(){
aposition();
var aUl = document.getElementById("ul1");
var aLi = document.getElementsByTagName("li");
var bBtn=true;
window.onscroll = function(){
	var veiwHeight = document.documentElement.clientHeight;
	var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
	var lastLi = aLi[aLi.length-1];
		if(posTop(lastLi) < veiwHeight + scrollY && bBtn){
					bBtn=false;
					//alert(bBtn);
			ajax("data.js?t="+new Date().getTime(),function(str){
				var json=eval("(" + str + ")");
				if(json.code){
							bBtn=true;
						}
				for(var i=0;i<json.list.length;i++){
							var list=json.list[i];
							for(var j=0;j<list.src.length;j++){
								var oLi =document.createElement("li");
								oLi.innerHTML="<img src="+list.src[j]+" /><p>"+list.title[j]+"</p>";
							    //alert(oLi.innerHTML);
								aUl.appendChild(oLi);
								aposition();
							}
						}
			});	

		}		
};

		

		//获取到屏幕的距离
		function posTop(obj){
			var top = 0;
			while(obj){
				top += obj.offsetTop;
				obj = obj.offsetParent;
			}
			return top;
		}
//定位布局三列
function aposition(){
	var aLi = document.getElementsByTagName("li");
	var aHeight = {L:[],C:[],R:[]};
	for(var i=0;i<aLi.length;i++){
		var iNow = i%3;
		switch(iNow){
			case 0:
				aLi[i].style.left="5px";
				hstep(aHeight.L);
			break;
			case 1:
				aLi[i].style.left="240px";
				hstep(aHeight.C);
			break;
			case 2:
				aLi[i].style.left="475px";
				hstep(aHeight.R);
			break;
		}
	}
	function hstep(dir){
		dir.push(aLi[i].offsetHeight);
		var step = Math.floor(i/3);
			if(!step){
				aLi[i].style.top=0;
			}else{
				var sum=0;
				for(var j=0;j<step;j++){
					sum += dir[j]+5;
				}
				aLi[i].style.top=sum+"px";
			}
	};
};
};
</script>

	<body>
		<div class="waterfall" id="div1">
			<ul id="ul1">
				<li>
					<img src="images/1.jpg" />
					<p>1111111111</p>
				</li>
				<li>
					<img src="images/2.jpg" />
					<p>222222222222222</p>
				</li>
				<li>
					<img src="images/3.jpg" />
					<p>333333333333</p>
				</li>
				<li>
					<img src="images/3.jpg" />
					<p>333333333333</p>
				</li>
				<li>
					<img src="images/4.jpg" />
					<p>444444444444</p>
				</li>
				<li>
					<img src="images/5.jpg" />
					<p>55555555555555</p>
				</li>
				<li>
					<img src="images/6.jpg" />
					<p>66666666666</p>
				</li>
				<li>
					<img src="images/7.jpg">
					<p>77777777777777</p>
				</li>
				<li>
					<img src="images/8.jpg">
					<p>88888888888</p>
				</li>
				<li>
					<img src="images/9.jpg">
					<p>9999999999</p>
				</li>
			</ul>
		</div>
	</body>
</html>	

 

 

 

data.js

 

{
	code:0,
	list:[
		{src:["images/1.jpg","images/2.jpg","images/3.jpg"],title:["1111","ssss","sdfsdf"]},
		{src:["images/4.jpg","images/5.jpg","images/7.jpg"],title:["1111","ssss","sdfsdf"]},
		{src:["images/3.jpg","images/6.jpg","images/8.jpg"],title:["1111","ssss","sdfsdf"]}
	]
}

 

ajax.js

function ajax(url, fnSucc, fnFaild)
{
	//1.创建Ajax对象
	if(window.XMLHttpRequest)
	{
		var oAjax=new XMLHttpRequest();
	}
	else
	{
		var oAjax=new ActiveXObject("Microsoft.XMLHTTP");
	}
	
	//2.连接服务器(打开和服务器的连接)
	oAjax.open('GET', url, true);
	
	
	//3.发送
	oAjax.send();
	
	//4.接收
	oAjax.onreadystatechange=function ()
	{
		if(oAjax.readyState==4)
		{
			if(oAjax.status==200)
			{
				//alert('成功了:'+oAjax.responseText);
				fnSucc(oAjax.responseText);
			}
			else
			{
				//alert('失败了'+oAjax.status);
				if(fnFaild)
				{
					fnFaild(oAjax.status);
				}
			}
		};
	};
};

images里面的图片就自己在网上下载下来就可以了。我这里的图片的宽度是210px 

 

2) 绝对寻址。即 Pinterest ,Mark之,KISSY ,花瓣网,百度图片,采用的方式:

  • 优点,可谓是最优的一种方案,方便添加数据内容,窗口变化,列数/数据块都会自动调整;
  • 缺点也有很多。
  • 后面的博客中会讲到,并做出代码来
  • 3) CSS3 定义。
  • 优缺点后面的博客中也会讲到,并做出代码来

 

今天的这篇博客就先讲出一种方式吧。后面两种2)和3)请期待后面的。。。。

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值