[转载] 简易Pinterest/瀑布流布局

转载至:rentj 

地址: http://www.cnblogs.com/rentj1/archive/2012/03/26/2417598.html

 

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
{width:210px; display:none}
.waterfall .item:hover
{opacity: 0.9}
.loading
{text-align:center; padding:20px 0 120px; }
</style>
</head>
<body>
<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>

 

posted @ 2012-05-16 16:07  飞花雪月  阅读(447)  评论(0编辑  收藏  举报