Pinterest/瀑布流布局
一 加载页面时,先页面中对已有元素进行定位。
使用对象保存每一列的列高度和列索引如:var column = {index:0, height:0};
使用列数组存放来这些对象。如:var columns = [column1,column2....];
使用cloumns.sort(function(x,y){return x.height - y.height}); 可以找出最短/最长高度的列的索引。
元素left= 列索引* 列宽 ; 元素top = 最短一列的高度;
二 鼠标滚动到最短一列的底部时动态加载数据。
if(文档scrollTop + 视口高度 > 容器距离文档顶部位置 + 最短一列的高度){
加载新内容
}
使用htmlElement.chidren属性可以只返回“htmlElement”的 元素类型子节点,不过IE中还会返回注释节点。htmlElement.childNodes 属性在非IE中除了返回元素类型子节点外,还返回注释和文本类型的子节点。要在childNodes里获取html元素节点,一般通过遍历然后比较 nodeType 进行过滤。每次 waterfall.appendChild(htmlElement.chidren[i]); htmlElement.chidren 里的元素个数减一,后面的元素自动向前移。
代码:
<!doctype html> <html> <head> <meta charset="gb2312"> <title>Pinterest/瀑布流布局</title> <style> .waterfall{position:relative; margin:0 auto;} .waterfall .item{210px; display:none} .waterfall .item:hover{opacity: 0.9} .loading{text-align:center; padding:20px 0 120px; } </style> </head> <body> <a href="javascript:void(null)" onClick="blank()">open</a> <h1>Pinterest/瀑布流布局</h1> <ul> <li>加载页面,动态数据块,透明度为0, 对已有元素进行定位</li> <li>问个瀑布流中的滚动加载数据问题? 页面高度(scrollHeight)- 浏览器视口高度(offsetHeight) + 浏览器滚动高度(scrollTop)</li> <li>鼠标滚动到最短一列的底部时加载数据</li> </ul> <h2>document clientWidth:</h2> <script> document.write(document.body.clientWidth + "<br>" + document.documentElement.clientWidth); var data = ' <div class="item"> \ <img src="http://pic4.xihuan.me/dr/192_287_90/t02e9a2932e981c0892.jpg" width="191" height="287"> \ </div>\ \ <div class="item"> \ <img src="http://pic2.xihuan.me/dr/192_288_90/t023a00b8fd90f13bf6.jpg" width="191" height="288">\ </div>\ \ <div class="item">\ <img src="http://pic2.xihuan.me/dr/192_128_90/t0261c1649fa0049796.jpg" width="192" height="128">\ </div>\ \ <div class="item"> \ <img src="http://pic2.xihuan.me/dr/192_136_90/t02f6128c27a03ba1b4.jpg" width="192" height="136"> \ </div>\ \ <div class="item"> \ <img src="http://pic3.xihuan.me/dr/192_288_90/t02999b00e78b0305fe.jpg" width="192" height="288">\ </div>\ \ <div class="item">\ <img src="http://pic1.xihuan.me/dr/192_267_90/t0285ead0935b33176e.jpg" width="191" height="267">\ </div>\ \ <div class="item"> \ <img src="http://pic3.xihuan.me/dr/192_144_90/t02fa12b10de9a6d67a.jpg" width="192" height="144">\ </div>\ \ <div class="item" > \ <img src="http://pic4.xihuan.me/dr/192_192_90/t025e949d4862320f73.jpg" width="192" height="192"> \ </div>\ \ <div class="item">\ <img src="http://pic0.xihuan.me/dr/192_266_90/t02b313f975b4fe3068.jpg" width="192" height="266">\ </div>\ \ <div class="item" > \ <img src="http://pic0.xihuan.me/dr/192_302_90/t0214baf4ab88314b2b.jpg" width="192" height="302">\ </div>\ \ <div class="item">\ <img src="http://pic2.xihuan.me/dr/192_256_90/t020b4d6b44ee7f086d.jpg" width="192" height="256">\ </div>\ \ <div class="item"> \ <img src="http://pic4.xihuan.me/dr/192_288_90/t024968e7e08f88a459.jpg" width="192" height="288"> \ </div>\ \ <div class="item">\ <img width="191" height="251" src="http://pic0.xihuan.me/dr/192_251_90/t02af8a0a7824408fcc.jpg">\ </div>\ \ <div class="item">\ <img width="192" height="192" src="http://pic0.xihuan.me/dr/192_192_90/t02664c86dbada6a50e.jpg"> \ </div>\ \ <div class="item"> \ <img width="192" height="152" src="http://pic0.xihuan.me/dr/192_152_90/t02c218bfbdd123c42b.jpg"> \ </div>\ \ <div class="item"> \ <img width="191" height="241" src="http://pic3.xihuan.me/dr/192_241_90/t026c1546d982d42d38.jpg">\ </div>\ \ <div class="item">\ <img width="191" height="288" src="http://pic3.xihuan.me/dr/192_288_90/t0238004c02f31c6c0c.jpg">\ </div>\ \ <div class="item" > \ <img width="191" height="427" src="http://pic2.xihuan.me/dr/192_427_90/t023f32089c91e6d53d.jpg"> \ </div>\ \ <div class="item" >\ <img height="176" width="192" src="http://pic4.xihuan.me/dr/192_176_90/t02b7c4366b32e0335d.jpg">\ </div>'; </script> <h2> document.documentElement.clientWidth</h2> <p> document.body.clientWidth body 元素宽度<br> document.documentElement.clientWidth html元素宽度 </p> <h2>htmlElement.chidren</h2> <p> 使用htmlElement.chidren属性可以只返回“htmlElement”的元素类型子节点,不过IE中还会返回注释节点。htmlElement.childNodes 属性在非IE中除了返回元素类型子节点外,还返回注释和文本类型的子节点。要在childNodes里获取html元素节点,一般通过遍历然后比较nodeType 进行过滤。 <br> 每次 waterfall.appendChild(htmlElement.chidren[i]); htmlElement.chidren 里的元素个数减一,后面的元素自动向前移。 </p> <div class="wrap"> <div id="Waterfall" class="waterfall"> <div class="item"> <img src="http://pic4.xihuan.me/dr/192_287_90/t02e9a2932e981c0892.jpg" width="191" height="287"> </div> <div class="item"> <img src="http://pic2.xihuan.me/dr/192_288_90/t023a00b8fd90f13bf6.jpg" width="191" height="288"> </div> <div class="item"> <img src="http://pic2.xihuan.me/dr/192_128_90/t0261c1649fa0049796.jpg" width="192" height="128"> </div> <div class="item"> <img src="http://pic2.xihuan.me/dr/192_136_90/t02f6128c27a03ba1b4.jpg" width="192" height="136"> </div> <div class="item"> <img src="http://pic3.xihuan.me/dr/192_288_90/t02999b00e78b0305fe.jpg" width="192" height="288"> </div> <div class="item"> <img src="http://pic1.xihuan.me/dr/192_267_90/t0285ead0935b33176e.jpg" width="191" height="267"> </div> <div class="item"> <img src="http://pic3.xihuan.me/dr/192_144_90/t02fa12b10de9a6d67a.jpg" width="192" height="144"> </div> <div class="item" > <img src="http://pic4.xihuan.me/dr/192_192_90/t025e949d4862320f73.jpg" width="192" height="192"> </div> <div class="item"> <img src="http://pic0.xihuan.me/dr/192_266_90/t02b313f975b4fe3068.jpg" width="192" height="266"> </div> <div class="item" > <img src="http://pic0.xihuan.me/dr/192_302_90/t0214baf4ab88314b2b.jpg" width="192" height="302"> </div> <div class="item"> <img src="http://pic2.xihuan.me/dr/192_256_90/t020b4d6b44ee7f086d.jpg" width="192" height="256"> </div> <div class="item"> <img src="http://pic4.xihuan.me/dr/192_288_90/t024968e7e08f88a459.jpg" width="192" height="288"> </div> <div class="item"> <img width="191" height="251" src="http://pic0.xihuan.me/dr/192_251_90/t02af8a0a7824408fcc.jpg"> </div> <div class="item"> <img width="192" height="192" src="http://pic0.xihuan.me/dr/192_192_90/t02664c86dbada6a50e.jpg"> </div> <div class="item"> <img width="192" height="152" src="http://pic0.xihuan.me/dr/192_152_90/t02c218bfbdd123c42b.jpg"> </div> <div class="item"> <img width="191" height="241" src="http://pic3.xihuan.me/dr/192_241_90/t026c1546d982d42d38.jpg"> </div> <div class="item"> <img width="191" height="288" src="http://pic3.xihuan.me/dr/192_288_90/t0238004c02f31c6c0c.jpg"> </div> <div class="item" > <img width="191" height="427" src="http://pic2.xihuan.me/dr/192_427_90/t023f32089c91e6d53d.jpg"> </div> <div class="item" > <img height="176" width="192" src="http://pic4.xihuan.me/dr/192_176_90/t02b7c4366b32e0335d.jpg"> </div> </div> <div class="loading" id="loading">正在加载……</div> </div> <script> var tool = { //此方法为了避免在 ms 段时间内,多次执行func。常用 resize、scoll、mousemove等连续性事件中 buffer: function(func, ms, context){ var buffer; return function(){ if(buffer) return; buffer = setTimeout(function(){ func.call(this) buffer = undefined; },ms); }; }, /*读取或设置元素的透明度*/ opacity: function(elem, val){ var setting = arguments.length > 1; if("opacity" in elem.style){//elem.style["opacity"] 读取不到CSS class中的值 return setting ? elem.style["opacity"] = val : elem.style["opacity"]; }else{ if(elem.filters && elem.filters.alpha) { return setting ? elem.filters.alpha["opacity"] = val*100 : elem.filters.alpha["opacity"]/100; } } }, //获取或设置文档对象的scrollTop //function([val]) documentScrollTop: function(val){ var elem = document; return (val!== undefined) ? elem.documentElement.scrollTop = elem.body.scrollTop = val : Math.max(elem.documentElement.scrollTop, elem.body.scrollTop); }, //function (elem) 获取elem在页面中的坐标 //return {top:xxx,left:xxx} offset: function (elem){ var top , left; if(!(elem && elem.offsetTop)) return null; top = elem.offsetTop; left = elem.offsetLeft; while(elem = elem.offsetParent){ top += elem.offsetTop; left += elem.offsetLeft; } return {top:top, left:left}; }, get: function(id){ return document.getElementById(id); }, addEventListener: function(elem, type, handel){ if(elem.addEventListener){ elem.addEventListener(type, handel, false); }else { elem.attachEvent("on"+type, function(){ handel.call(elem, window.event); }); } } }; function wrap(elem){ return new DomWrap(elem); } function DomWrap(elem){ this.core = tool; this.dom = elem; } DomWrap.prototype={ on: function(type, handel){ this.core.addEventListener(this.dom, type, handel); } }; //Waterfall (function(ns, dom){//dom:DomWrap //静态私有成员 var viewportHeight = document.documentElement.clientHeight; var minHeight = 0; var columnCount = 5; var columnWidth= 210; var cloumns = []; var waterfall = ""; var staticElems = []; var baseTop = 0; //初始化 function init(container){ waterfall = tool.get(container); staticElems = waterfall.children; baseTop = tool.offset(waterfall).top; for(var i=0; i< columnCount; i ++){ cloumns[i] = {index:i, height:0}; } waterfall.style.width = (columnWidth*columnCount)+"px"; dom(window).on("scroll",tool.buffer(onscroll,500)); position(staticElems); } //设置元素位置 function position(elems, append){ var left, top, cssText; var appedElem = null; var sortedCloumns = []; for(var i=0, n= elems.length; i< n;) { if(!(elems[i] && elems[i].nodeType ===1)) continue; cloumns.sort(function(x,y){return x.height - y.height}); index = cloumns[0].index; left = index * columnWidth top = cloumns[0].height; cssText = "display:block; position:absolute; left:" + left + "px; top:" + top + "px"; elems[i].style.cssText = cssText; if(append){ apendItem = elems[i]; waterfall.appendChild(apendItem); cloumns[0].height += apendItem.offsetHeight; n--; } else { cloumns[0].height += elems[i].offsetHeight; i++; } } cloumns.sort(function(x,y){return x.height - y.height}); minHeight = cloumns[0].height; waterfall.style.height = cloumns[cloumns.length-1].height + "px"; } function appendItem(){ var fragment = document.createElement("div"); fragment.innerHTML = data; position(fragment.children,true); } function onscroll(){ var scrollTop = tool.documentScrollTop(); if(scrollTop + viewportHeight > baseTop + minHeight ) { //console.log("loading"); appendItem(); } } ns.watferfall = init; }( window, wrap)); watferfall("Waterfall"); </script> </body> </html>