前段时间看到同学的博客,关于工作的技术博文,里面提到了瀑布流。
瀑布流这个东西听到很多,也看过一些文章,不过就没自己动手试过。没追求,所以至今不成大器,技术一直这么渣。。。
先看一下
瀑布流的几种常见实现方式:
1)传统多列布局(本文采用这种)
2)css3定义
3)绝对定位
写这个demo的时候,最多的是参考张鑫旭大神的文章 ,所以demo的图片来源也是效仿他的,从迅雷UED取的~~
代码:
var Waterfall = (function() { var colNum = 3, //列数 imgRoot = 'http://cued.xunlei.com/demos/publ/img/', //图片路径 imgIndex = 0, //当前图片索引 perNum = 9, //每次请求图片数 totalImg = 160; //图片总数 function $(id) { return document.getElementById(id); } //获取最短列 function colShortest() { var shortest = 0; // console.log(shortest + ': ' + $('col' + shortest).offsetHeight); for(var i = 1; i < colNum; i += 1) { // console.log(i + ': ' + $('col' + i).offsetHeight); if($('col' + i).offsetHeight < $('col' + shortest).offsetHeight) { shortest = i; } } // console.log('shortest: ' + shortest + '\n'); return shortest; } //获取当前需要图片url function getImgUrl() { var index = imgIndex; if(imgIndex < 10) { index = '00' + imgIndex; }else if(imgIndex < 100) { index = '0' + imgIndex; } return imgRoot + 'P_' + index + '.jpg'; } //每滚动到页面底部就更新一下页面 function render() { if(isToBottom()) { $('loading').style.display = 'block'; appendItem(perNum); } } //创建一个项 function createItem() { var frag = document.createDocumentFragment(), div = document.createElement('div'), imgUrl = getImgUrl(), img = ''; div.className = 'item'; div.innerHTML = img; frag.appendChild(div); return frag; } //append num个图片 function appendItem(num) { var newItem = []; for(var i = 0; i < num; i += 1) { if(totalImg >= 0) { newItem.push(createItem()); imgIndex += 1; totalImg -= 1; } } var curCol = 0; for(var i = 0, len = newItem.length; i < len; i += 1) { if(curCol >= colNum) { curCol = 0; } $('col' + curCol).appendChild(newItem[i]); // $('col' + colShortest()).appendChild(newItem[i]); curCol += 1; } $('loading').style.display = 'none'; } //增加一个图片项 // function appendItem() { // var frag = document.createDocumentFragment(), // div = document.createElement('div'), // imgUrl = getImgUrl(), // image = new Image(), // img = ''; // div.className = 'item'; // div.innerHTML = img; // frag.appendChild(div); // colShortest().appendChild(frag); // } //判断是否滚动到底部 function isToBottom() { var scrollT = document.body.scrollTop || document.documentElement.scrollTop, //滚动高度 winH =document.documentElement.clientHeight, //窗口可视高度 bodyH = document.body.offsetHeight; //正文高度 if((bodyH - scrollT) <= (winH + 10)) { return true; } return false; } //初始化 function init() { appendItem(15); //先加载15张图片 window.onscroll = function() { //滚动事件 render(); } } return { init:init } })();Waterfall.init();
在写这个demo的过程中遇到了一个问题,就是原本思路每次取9张图片,然后循环插入到当前最短列中去,但是。。。我果然想得太简单了,真实情况它会将9张图片全部插入到同一列中,根本原因是在计算最短列的时候,之前插入的图片还没插好所以计算的时候没有算到,导致最短列经常是同一个。。。所以,改了,改成将取到的图片分别插入不同列。这样的话,虽然均匀了一点,但是还是存在问题,因为这样的插入法就是说每一个差不多有同样多张的图片,如果某一列中长的图片比较多,某一列中短的图片又比较多的话,那么,最终长度也会参差不齐的。。。现在这个demo就是了:
很简陋的一个瀑布流,代码很水,还要改进