waterfall瀑布流网页实现的设计方案一:Masonry
waterfall 瀑布流网页实现的设计方案一:Masonry(含loading几次后出现分页)
瀑布流设计早就不是什么新鲜的东西了,现在网上基于瀑布流的网页非常常见,这种设计能给浏览器者更直接更有效率的浏览体验。
那么我们可以如何从前端、后端配合去实现这种效果呢?
其实目前已有很多基于jquery或原生态javascript的waterfall插件,我们只需要根据api进行运用,既可做到不错的瀑布流网页。
但是在这些插件中,做得兼容性好并且功能还不错的,首推下面两种:
1.Masonry
2.KISSY
下面一一解说下这两种瀑布流方式的实现方式。本文只说Masonry,KISSY将会在下一篇文章更新。
需求:瀑布流输出,loading 5 次后出现分页,每次loading 12个内容。
jquery虽然不是必须的,但是为了方便,我们还是用上jquery吧。
下面的例子基于phpcms
jquery.min.js 及 masonry.pkgd.min.js请自行下载。
一、html代码:
代码如下 | 复制代码 |
<script language="javascript" type="text/javascript" src="/statics/js/1.7.2/jquery.min.js"></script> <script src="/statics/js/masonry.pkgd.min.js"></script> <style> #content {min-height: 390px; width: 920px; } #content a {text-decoration: none; } #page_loading {display: none; background: #111111; opacity: 0.7; height: 60px; width: 220px; padding: 10px; text-align:center; } #thumbs {position: relative; width: 895px; padding: 10px 0 20px 15px; } #thumbs a {color: #26ADF5; } .imgbox {opacity: 0; position: absolute; max-width: 260px; margin: 5px 5px 5px 5px; -moz-border-radius:6px; -webkit-border-radius:6px; border-radius:6px; border:1px solid #EEE; -webkit-box-shadow:0 0 6px #EEE; -moz-box-shadow:0 0 6px #EEE; padding: 1px; float: left; background: #FFF; z-index: 100; } .imgbox img {display: block; padding: 6px; max-width: 250px; } .imgbox .img_user {display: block; color: #26ADF5; padding: 3px 6px 2px 6px; } .imgbox .img_time {display: block; color: #AAA; padding: 3px 6px 5px 6px; float: left; } #page_nav {clear: both; height: 25px; width: 920px; font-size: 12pt; text-align: center; } .page_nav {margin: 0 auto; text-align: left; overflow: hidden; } .page_nav a {display: block; padding-top: 4px; margin-right: 10px; float: left; } .page_nav_but {color: #26ADF5; } .current {color: #26ADF5; margin-top: -4px; font-size: 16pt; } #next_page {display: none; } #stopfetch {display: none; width: 100px; height: 100px; position: fixed; top:48%; right:8%; background: url(../images/stopfetch.png) no-repeat; } #stopfetch img {opacity: 0; } </style> </head> <body> <div id="content"> <!-- 包含所有图片的容器 --> <div id="thumbs"> <!-- 各个图片的容器 --> {loop $datas $r} <!-- 这里输出第一页的内容,请根据不同的语言套上相应标签,本例子基于phpcms --> <div class="imgbox" itemscope itemtype="http:///ImageObject"> <a href="{$r['url']}" title="{$r['desc']}"> <img src="{$r['thumb']}" alt="{$r['desc']}" itemprop="contentURL" /> </a> <span class="img_user" itemprop="author"><a href="{$r['url']}">{$r['desc']}</a></span> <span class="img_time" itemprop="datePublished">@<time datetime="<?php echo date('Y-m-d H:i:s',$r['inputtime']);?>" itemprop="datePublished"><?php echo date('Y-m-d H:i:s',$r['inputtime']);?></time> #5</span> </div> {/loop} </div> </div> <div id="next_page"> <a href="/lists-ajax1-{$catid}-{$page}-2-12.html">下一页</a> <!-- 这里设置下一个loading的url地址,本例子基于phpcms --> </div> <div id="page_loading"> <span>给力加载中……</span> </div> <a class="backToTop"></a> <script type="text/javascript"> //loading 5 次,出现分页! var loading_times = 5; // waterfall与 loading 几次后出现分页实现 $(function() { $('.imgbox').css({display: 'none'}); $("#thumbs .imgbox").css({ opacity: 1 }); // 流体布局 var $container = $('#thumbs'); $container.imagesLoaded(function(){ $container.masonry({ columnWidth: 279, itemSelector : '.imgbox' }); $('.imgbox').show(); }); var request, nextHref = $("#next_page a").attr("href"); $(window).bind("scroll", function(){ if( $(document).scrollTop() + $(window).height() > $(document).height() - 10 ) { if( nextHref != undefined ) { if(request && request.readyState != 4 ) { request.abort(); } // Ajax waterfall loading request = $.ajax( { url: $("#next_page a").attr("href"), type: "POST", beforeSend: function(){ $("#page_loading").show("slow"); }, success: function(data) { result = $(data).find(".imgbox"); nextHref = $(data).find("#next_page a").attr("href"); newNav = $(data).find("#page_nav"); $("#next_page a").attr("href", nextHref); $("#page_nav").remove(); $container.after(newNav); $("#thumbs").append(result); // 重新计算 .page_nav 的宽带,以便 margin: 0 auto 生效 $page_navwidth = $(".page_nav").children().length * 23; $(".page_nav").css({ opacity: 0, width: $page_navwidth }); $newElems = result; $newElems.imagesLoaded(function(){ $container.masonry( 'appended', $newElems, true ); // 渐显新的内容 $newElems.animate({ opacity: 1 }); $("#stopfetch").show("slow"); $("#page_loading").hide("slow"); }); //当前页的loading次数 sub_page = $(data).find("#sub_page").html()-1; //当前页数 current_page = $(data).find("#current_page").html(); //总页数 total_page = $(data).find("#total_page").html(); if(sub_page>=loading_times || sub_page+loading_times*(current_page-1) >= total_page) { if($('.Pager').length==0) { $("#content").append("<div class="Pager">"+$(data).find("#page_str").html()+'</div>'); } $(window).unbind('scroll'); $("#page_loading").hide(); return; } } }); } else { $("#page_loading span").text("木有了噢,最后一页了!"); $("#page_loading").show("fast"); setTimeout("$('#page_loading').hide()",1000); setTimeout("$('#page_loading').remove()",1100); } } }); }); (function ($) { var $backEle = $('.backToTop'); $backEle.click( function () { $("html,body").animate({ scrollTop: 0 }, 120); }) $backTOfuc = function () { var st = $(document).scrollTop(); var winH = $(window).height(); (st > 188) ? $backEle.show() : $backEle.hide(); if (!window.XMLHttpRequest) { $backEle.css("top", st + winH - 166); } } $(window).bind("scroll.backToTop", $backTOfuc); $(function () { $backTOfuc(); }); })(window.jQuery) </script> |
二、php端代码:/lists-ajax1-{$catid}-{$page}-2-12.html
这里的四个参数分别对应:$_GET['catid'],$_GET['page'],$_GET['sub_page'],$_GET['limit']
代码如下 | 复制代码 |
... ... //loading 5 次,出现分页! $loading_times = 5; $sub_page = (int)$_GET['sub_page']; $page_c = $sub_page; $page = (int)$_GET['page']; if($page==0) { $page = 1; } $sub_page = $sub_page+($page-1)*$loading_times; $limit = (int)$_GET['limit']; $sql = "....."; //这里根据具体sql语句查询出结果数组,请根据自己的系统写好。 $datas = getRowset($sql,' a.id asc ', $sub_page, $limit,10,$urlrule); //返回的结果数组应该包含: //1.当前页的loading page:$sub_page,2.总记录数:total_count,3.总页数:total_pages,4.结果数组 datas $result['stat']='ok'; $result['photos']['page']=$sub_page; $result['photos']['pages']=$datas['total_pages']; $result['photos']['perpage']=$limit; $result['photos']['total']=$datas['total_count']; $result['photos']['photo']=$datas['datas']; //这里是获取分页代码的str,请注意这里的$limit*$loading_times 这个参数 $datas_tmp = getRowset($sql,' a.id asc ', $page, $limit*$loading_times,10,$urlrule); $result['photos']['pages_str']=$datas_tmp['pages_str']; //下面是组装返回的字符串!供前端的js获取使用 $str='<div id="thumbs">'; foreach($result['photos']['photo'] as $k=>$r) { $str.=" <div class="imgbox" itemscope itemtype="http:///ImageObject"><a href="".$r['url']."" title="".$r['desc'].""><img src="".$r['thumb']."" alt="".$r['desc']."" itemprop="contentURL" /></a><span class="img_user" itemprop="author"><a href="".$r['url']."">".$r['desc']."</a></span><span class="img_time" itemprop="datePublished">@<time datetime="".date('Y-m-d H:i:s',$r['inputtime'])."" itemprop="datePublished">".date('Y-m-d H:i:s',$r['inputtime'])."</time></span></div>"; } $page_c++; $str.="<div id="next_page"><a href="/lists-ajax1-{$catid}-{$page}-{$page_c}-{$limit}.html">下一页</a></div><div id="sub_page">{$page_c}</div><div id="current_page">{$page}</div><div id="total_page">".$result['photos']['pages']."</div><div id="page_str">".$result['photos']['pages_str']."</div></div>"; echo $str;die; |
waterfall瀑布流网页实现的设计方案二:KISSY
需求:瀑布流输出,loading 5 次后出现分页,每次loading 12个内容。
jquery虽然不是必须的,但是为了方便,我们还是用上jquery吧。
html+js代码:
代码如下 | 复制代码 |
.... <script language="javascript" type="text/javascript" src="/statics/js/1.7.2/jquery.min.js"></script> <script src="http://g.tbcdn.cn/kissy/k/1.3.2/seed.js" data-config="{combine:true}"></script> ... ... <div id="wrapper"> <div id="article"> <div id="ColumnContainer" style="zoom: 1"> </div> <div id="loadingPins">loading...</div> </div> </div> <a class="backToTop"></a> <script type="tpl" id="tpl"> <div class="pin ks-waterfall" data-id="{id}"> <a href="{url}" class="image" target='_blank'> <img alt="{desc}" height="{height}" style="height:{height}px" src="{image}" /> </a> <p class="description">{desc}</p> </div> </script> <script type="text/javascript"> KISSY.use("waterfall,ajax,node,button", function(S, Waterfall, IO, Node, Button) { //loading 5 次,出现分页! var loading_times = 5; var $ = Node.all; //每次loading出现的记录数 var per_count = 12; var tpl = $('#tpl').html(), nextpage = 1, waterfall = new Waterfall.Loader({ container:"#ColumnContainer", load:function(success, end) { $('#loadingPins').show(); new IO({ url:'/lists-ajax-{$catid}-{$page}-'+nextpage+'-'+per_count+'.html', dataType: "html", success: function(d) { //将json字符串变成 json格式数据 var d =(new Function("","return "+d))(); // 如果数据错误, 则立即结束 if (d.stat !== 'ok') { alert('load data error!'); end(); return; } // 拼装每页数据 var items = []; S.each(d.photos.photo, function(item) { item.height = Math.round(Math.random()*(300 - 180) + 180); // fake height items.push(new S.Node(S.substitute(tpl,item))); }); success(items); var page_it = (d.photos.page)-(loading_times*({$page}-1)); // 如果到最后一页了, 也结束加载 nextpage = page_it + 1; if ((nextpage >loading_times)||((nextpage+(loading_times*({$page}-1))) >= d.photos.pages)) { if($('.Pager').length==0) { $('#wrapper').append("<div class="Pager">"+d.photos.pages_str+'</div>'); } end(); } }, complete: function() { $('#loadingPins').hide(); } }); }, minColCount:2, colWidth:228 }); }); (function ($) { var $backEle = $('.backToTop'); $backEle.click( function () { $("html,body").animate({ scrollTop: 0 }, 120); }) $backTOfuc = function () { var st = $(document).scrollTop(); var winH = $(window).height(); (st > 188) ? $backEle.show() : $backEle.hide(); if (!window.XMLHttpRequest) { $backEle.css("top", st + winH - 166); } } $(window).bind("scroll.backToTop", $backTOfuc); $(function () { $backTOfuc(); }); })(window.jQuery) </script> |
二、php端代码:
lists-ajax-{$catid}-{$page}-’+nextpage+’-'+per_count+’.html
四个参数分别对应:$_GET['catid'],$_GET['page'],$_GET['sub_page'],$_GET['per_page']
代码如下 | 复制代码 |
... ... //loading 5 次,出现分页! $loading_times = 5; $sub_page = (int)$_GET['sub_page']; $page = (int)$_GET['page']; if($page==0) { $page = 1; } $sub_page = $sub_page+($page-1)*$loading_times; $limit = (int)$_GET['per_page']; $catids=implode(',',$array_child); if($catids!='') { $catids.=','.$catid; } else { $catids=$catid; } $sql = "..."; $datas = getRowset($sql,' a.id asc ', $sub_page, $limit,10,$urlrule); $result['stat']='ok'; $result['photos']['page']=$sub_page; $result['photos']['pages']=$datas['total_pages']; $result['photos']['perpage']=$limit; $result['photos']['total']=$datas['total_count']; $result['photos']['photo']=$datas['datas']; $datas_tmp = getRowset($sql,' a.id asc ', $page, $limit*$loading_times,10,$urlrule); $result['photos']['pages_str']=$datas_tmp['pages_str']; //$jsonp_callback = $_GET['json_callback']; echo json_encode($result);die; |