背景:
1、在移动端开发,jq文件是显得非常庞大的,所以所有效果尽量用HTML5和原生js实现。
2、本次瀑布流是固定列数,采用非浮动的另外一种瀑布流思想实现的。
3、本次数据来源是json接口
4、考虑到一次性奖json加载到页面数据比较臃肿,所以本demo是当点击加载更多时再重新发出数据请求(非ajax)
先上完整demo代码
1 <!doctype HTML> 2 <html> 3 <head> 4 <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"/> 5 <meta content="black" name="apple-mobile-web-app-status-bar-style"/> 6 <meta content="telephone=no" name="format-detection"/> 7 <meta id="twcClient" content="false" name="twcClient"/> 8 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 9 <title>瀑布流demo</title> 10 <style type="text/css"> 11 html{padding:0px;margin:0px auto;-webkit-text-size-adjust:none;} 12 body{background:#FFF;padding:0px;margin:0px auto;font-size:15px;color:#333;font-family:Helvetica,Microsoft YaHei,Microsoft JhengHei;} 13 a{color:#333;text-decoration:none;} 14 a:visited{color:#333;} 15 ol,ul,li,dl,dd,dt{padding:0;margin:0;list-style:none;} 16 form,p{padding:0;margin:0;} 17 i,em{font-style:normal;} 18 textarea {resize:none} 19 img{border:none;} 20 .spanclass{display:none;} 21 .body{max-width:320px;margin:0 auto;overflow:hidden;background:#eee;} 22 23 /*列表页图片*/ 24 .waterFall {margin: 0 auto;text-align: center;width: 320px;} 25 .l-uPic{padding-top: 10px; width: 150px; display: inline-block; vertical-align: top} 26 .l-uPic li{border: 1px solid #c9c9c9;margin-bottom:10px; width: 147px; background: #fff} 27 .l-uPic li a{ display: block; position: relative;} 28 .l-uPic li img{ padding: 6px;background: #fff; vertical-align: top} 29 .l-uPic li span{ display: block; height: 28px; line-height: 28px; border-top: 1px dashed #d5d5d5; font-size: 16px; background: #f7f7f7; padding-left: 10px;} 30 .l-uPic li span em{ float: right; height: 14px; line-height: 14px; color: #fff; background: #cc6698; padding: 0 2px; font-size: 10px; margin-top: 7px; margin-right: -2px;} 31 .l-uPic li span em::before {border-width:7px; border-color:transparent #cc6698 transparent transparent; border-style: solid; width: 0; height: 0; content: ""; display: inline-block; margin-left: -16px; vertical-align: middle; margin-top: -1px;} 32 .l-uPic li .iType{ position: absolute; height: 15px; line-height: 15px; background: #090909; right: 6px; bottom: 35px; border-radius: 7px; color: #fff; font-size: 11px; padding: 0 6px;} 33 .l-uPic li .iTime{ color: #b3b3b3; text-align: right; display: block;font-size: 12px; padding:7px 3px 9px 0;} 34 .l-uPic li .iTit { display: block; font-size: 13px; padding: 0 3px 0 6px; line-height: 18px; text-align: left;} 35 .l-uPic li .iTit em{ color: #c69;} 36 .l-uPic li .iNews{ display: block; height: 17px; line-height: 17px; background: #3da7de; color: #fff; font-size: 12px; font-style: italic; width: 42px; text-align: center; margin: 4px 0 6px -5px;} 37 .l-uPic li .iNews:before{display:inline-block;content:"";position:absolute;top:-4px;left:-5px;border-style:solid;border-color:transparent transparent #2381b2 #2381b2;border-width:2px;-webkit-transform: rotate(-90deg);} 38 39 /*查看更多*/ 40 .btn-more{border:1px solid #d9d6d6;border-radius:5px;background:#F5F5F5;line-height:36px;margin:10px 7px;text-align:center;cursor:pointer;} 41 .btn-more a {display:block;height:36px;line-height:36px;color:#777;font-size: 14px;} 42 .btn-more a i{display:inline-block;width:0;height:0;border-width:6px;overflow:hidden;border-color:#777 transparent transparent;border-style:solid;vertical-align:middle;position:relative;top:2px;margin-left:5px;} 43 </style> 44 </head> 45 <body> 46 <div class="body"> 47 48 <div id="JwaterFall" class="waterFall"> 49 <ul class="l-uPic"> 50 <li class="item"> 51 <a href="#"> 52 <i class="iNews">NEWS</i> 53 <i class="iTit"><em>[时装]</em><br/>解禁深海无人区!潜水 表误区大扫盲</i> 54 <i class="iTime">2013-08-07</i> 55 </a> 56 </li> 57 </ul> 58 <ul class="l-uPic"> 59 <li class="item"> 60 <a href="#"> 61 <img src="http://dummyimage.com/135x135/ddd/79c" width="135" alt=""> 62 </a> 63 </li> 64 </ul> 65 66 </div> 67 <div class="btn-more" id="Jmore"><a>查看更多<i></i></a></div> 68 69 </div> 70 71 <script type="text/javascript"> 73 // 获取字符实际长度 74 var jmz = {}; 75 jmz.GetLength = function(str) { 76 return str.replace(/[^\x00-\xff]/g,"aa").length; 77 }; 78 /** 79 * 图片头数据加载就绪事件 - 更快获取图片尺寸 80 * @version 2011.05.27 81 * @author TangBin 82 * @see http://www.planeart.cn/?p=1121 83 * @param {String} 图片路径 84 * @param {Function} 尺寸就绪 85 * @param {Function} 加载完毕 (可选) 86 * @param {Function} 加载错误 (可选) 87 * @example imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () { 88 alert('size ready: width=' + this.width + '; height=' + this.height); 89 }); 90 */ 91 var imgReady = (function () { 92 var list = [], intervalId = null, 93 // 用来执行队列 94 tick = function () { 95 var i = 0; 96 for (; i < list.length; i++) { 97 list[i].end ? list.splice(i--, 1) : list[i](); 98 }; 99 !list.length && stop(); 100 }, 101 102 // 停止所有定时器队列 103 stop = function () { 104 clearInterval(intervalId); 105 intervalId = null; 106 }; 107 108 return function (url, ready, load, error) { 109 var onready, width, height, newWidth, newHeight, 110 img = new Image(); 111 img.src = url; 112 // 如果图片被缓存,则直接返回缓存数据 113 if (img.complete) { 114 ready.call(img); 115 load && load.call(img); 116 return; 117 }; 118 119 width = img.width; 120 height = img.height; 121 122 // 加载错误后的事件 123 img.onerror = function () { 124 error && error.call(img); 125 onready.end = true; 126 img = img.onload = img.onerror = null; 127 }; 128 129 // 图片尺寸就绪 130 onready = function () { 131 newWidth = img.width; 132 newHeight = img.height; 133 if (newWidth !== width || newHeight !== height || 134 // 如果图片已经在其他地方加载可使用面积检测 135 newWidth * newHeight > 1024 136 ) { 137 ready.call(img); 138 onready.end = true; 139 }; 140 }; 141 onready(); 142 143 // 完全加载完毕的事件 144 img.onload = function () { 145 // onload在定时器时间差范围内可能比onready快 146 // 这里进行检查并保证onready优先执行 147 !onready.end && onready(); 148 load && load.call(img); 149 // IE gif动画会循环执行onload,置空onload即可 150 img = img.onload = img.onerror = null; 151 }; 152 153 // 加入队列中定期执行 154 if (!onready.end) { 155 list.push(onready); 156 // 无论何时只允许出现一个定时器,减少浏览器性能损耗 157 if (intervalId === null) intervalId = setInterval(tick, 40); 158 }; 159 }; 160 })(); 161 162 163 var JwaterFall = document.getElementById('JwaterFall'),//外壳 164 Jmore = document.getElementById('Jmore'),//更多按钮 165 JwaterFallLeft = JwaterFall.getElementsByTagName('ul')[0],//左列 166 JwaterFallRight = JwaterFall.getElementsByTagName('ul')[1],//右列 167 pNo = 0, 168 oClick = false; 169 170 //初始值 171 var waterFallData = { 172 index : 0,//全局加载个数 173 loopNum : 0,//每次加载个数 174 errorNum : 0,//每次加载错误个数 175 unloadNum : 0,//全局未加载个数 176 otherHeight : 18,//一行标题文字的高度 177 heightLeft : JwaterFallLeft.clientHeight,//左列高度 178 heightRight : JwaterFallRight.clientHeight,//右列高度 179 heightLeftJson : [],//左列json数组 180 heightRightJson : []//右列json数组 181 } 182 183 function append (data,num,pageCount) { 184 function appendjson() { 185 //当加载个数完成时,插入每列对应元素,并清空 186 if (waterFallData.loopNum + waterFallData.errorNum +waterFallData.unloadNum == num) { 187 for (var i = 0 , len=waterFallData.heightLeftJson.length; i < len ; i++) { 188 JwaterFallLeft.appendChild(waterFallData.heightLeftJson[i]); 189 } 190 waterFallData.heightLeftJson = []; 191 for (var i = 0 , len=waterFallData.heightRightJson.length; i < len ; i++) { 192 JwaterFallRight.appendChild(waterFallData.heightRightJson[i]); 193 } 194 //加载成功 , 重置 195 waterFallData.loopNum = 0; 196 waterFallData.errorNum = 0; 197 waterFallData.heightRightJson = []; 198 if (pNo >= pageCount) { 199 Jmore.onclick = null; 200 Jmore.innerHTML = "没有啦!"; 201 }else { 202 oClick = true; 203 Jmore.innerHTML = "<a>查看更多<i></i></a>"; 204 } 205 } 206 } 207 208 if (pNo > pageCount) { 209 waterFallData.unloadNum++;//未加载+1 210 appendjson();//当加载个数完成时,插入每列对应元素,并清空 211 Jmore.onclick = null; 212 Jmore.innerHTML = "没有啦!"; 213 }else { 214 if(!data[waterFallData.index]){ 215 waterFallData.index=0; 216 } 217 var jsonSrc = data[waterFallData.index].image, 218 jsonUrl = data[waterFallData.index].url, 219 jsonPubDate = data[waterFallData.index].pubDate, 220 jsonTitle = data[waterFallData.index].title, 221 jsonType = data[waterFallData.index].type, 222 jsonTitlen = jmz.GetLength(jsonTitle)+jmz.GetLength(jsonType); 224 225 if(jsonType !=''){ 226 jsonType = '<em>['+jsonType+']</em>'; 227 jsonTitlen = jsonTitlen+2; 228 } 229 imgReady(jsonSrc, function () { 230 //图片尺寸加载完成时 231 //如果图片不为空 232 if (this.width != 0) { 233 //创建item 234 var liEle = document.createElement("li"); 235 236 liEle.innerHTML = '<a href="' + jsonUrl + '"><img src="' + jsonSrc + '" width="135" /><i class="iTit">'+jsonType+jsonTitle+'</i><i class="iTime">'+jsonPubDate+'</i></a>'; 237 //每次计算左右两列高度,并且插入相应的数组 240 if (waterFallData.heightLeft > waterFallData.heightRight) { 241 waterFallData.heightRightJson.push(liEle); 242 waterFallData.heightRight = waterFallData.heightRight + 135*this.height/this.width + waterFallData.otherHeight*Math.ceil(jsonTitlen/21); 243 244 }else { 245 waterFallData.heightLeftJson.push(liEle); 246 waterFallData.heightLeft = waterFallData.heightLeft + 135*this.height/this.width + waterFallData.otherHeight*Math.ceil(jsonTitlen/21); 247 //alert("l:"+waterFallData.heightLeft) 248 } 249 } 250 waterFallData.loopNum++; 251 appendjson();//当加载个数完成时,插入每列对应元素,并清空 252 },function () { 253 //图片加载完成时 254 },function () { 255 //图片加载出错时 256 waterFallData.errorNum++; 257 }); 258 259 waterFallData.index++;//全局+1 260 } 261 }; 262 263 function callback(data) { 264 var articleList = data.articleList, 265 pageCount = data.pageCount-1, 266 leng=articleList.length; 267 268 Jmore.innerHTML = "正在加载..."; 269 for (var i = 0 , len=leng; i < len ; i++) { 270 append (articleList,leng,pageCount); 271 } 272 Jmore.onclick = function () { 273 if(oClick){ 274 oClick = false; 275 this.innerHTML = "正在加载..."; 276 pNo++; 277 getDetails(pNo); 278 }else{ 279 Jmore.onclick = null; 280 } 281 282 }; 283 } 284 285 function getScript(url) { 286 var scr = document.createElement('script'); 287 scr.src = url; 288 scr.charset = "utf-8"; 289 document.body.insertBefore(scr, document.body.firstChild); 290 } 291 292 function getDetails(pNo) { 293 var url = "http://www.pclady.com.cn/3g/wap2013/intf/shouye/index_"+pNo+".html"; 294 getScript(url); 295 } 296 297 document.write("<script src=\"http://www.pclady.com.cn/3g/wap2013/intf/shouye/index.html\" charset=\"utf-8\"><\/script>") 298 </script> 299 300 </body> 301 </html>
代码比较多点,但胜在是原生,比请求个jq还是有优势的。