仿pinterest实现瀑布流布局效果

在张鑫旭的博客里,有一片文章介绍 瀑布流 实现的文章,(要查看演示,请单击DEMO)本文是在其基础上进行的二次开发,使其更具实用性。

 

 

这里,主要涉及数据从数据库里读取,单击图片可以缩放等。

本文附件附带的源代码,有兴趣可以下载看看

下载的程序打开pic.aspx页面显示图片列表(您需要手动输入测试数据)。

 

单击图片会出现缩放等,除此外,还可以分页,(排序),以及设置页面大小等。

 

 

 下面介绍本程序的大致实现。

 

 

1.建立数据库

见附件里SQL.txt,为了使得效果更明显,需要输入测试数据,越多越好

 

2.返回JSON数据 (ajax_getpics.aspx 页面)

 

返回数据使用了自定义分页,这里使用了SQL2005+上的Row_Number()函数。在GetData里,还有3个参数:orderby设置数据排序方式(一般网站的图片,都会让用户按照最新上传,点击率,回复率排序),预留这个参数就是为了解决这个问题。

pageIndex是通过传递的URL来获取的,也就是用户访问了第几页

pageSize设置页面的大小,在本演示中,设置了200.

        public DataTable GetData()
        {
            string orderBy = "pic_id";
            int pageIndex = int.Parse(Request["pageIndex"]);
            int pageSize = int.Parse(Request["pageSize"]);

            string sql = @"
declare @startRowIndex int 
set @pageIndex=@pageIndex-1 
set @startRowIndex=@pageIndex*@pageSize+1;


WITH PICList AS
( 
  select pic_id,user_id,orginpath,description,thumpath, commpeople,
  click,
  ROW_NUMBER() OVER (ORDER BY pic_id DESC) as RowNum 
   FROM    love_pics where isapproved=1
)
  
 Select * from  PICList WHERE RowNum BETWEEN @startRowIndex AND (@startRowIndex + @pageSize-1)  order by " + orderBy + @" desc " ;





            DataTable ds = new DataTable();
            SqlConnection conn = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["con"].ConnectionString);
            SqlCommand dCmd = new SqlCommand();

            dCmd.Parameters.AddWithValue("@pageIndex", pageIndex);
            dCmd.Parameters.AddWithValue("@pageSize", pageSize);
            dCmd.Parameters.AddWithValue("@orderBy", orderBy);

            dCmd.CommandText = sql;
            dCmd.Connection = conn;
            SqlDataAdapter da = new SqlDataAdapter();
            da.SelectCommand = dCmd;
            da.Fill(ds);
            return ds;
        }

 

 

3.制作瀑布页面 pic.aspx

在开始前,我们先定义一个页面大小pageSize和自定义分页的实现。关于Pagination可以参考源代码里具体实现。

  public int pageindex = 1;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!string.IsNullOrEmpty(Request.QueryString["currentpage"]))
        {
            pageindex = int.Parse(Request.QueryString["currentpage"]);
        }

        string sql = " Select count(*) from love_pics where isapproved=1 ";
        
        // string i = DBHelper.Instance.ExeScalar(sql).ToString();
        string i = "1000";

        //执行上面SQL语句,即可返回记录说,这里使用了硬编码,加上是100页
       
        //附带的1=1只是用于演示如何自带参数
        litPaging2.Text = litPaging1.Text = Pagination(int.Parse(i), 200, pageindex, "pic.aspx?1=1&");

    }

 

 

4.获取JSON返回的数据,也就是用JQuery的getJSON,没设么特别的,其中pageindex是我们后台定义的页码。 后面自动跟了一个random是因为

js在请求时,即使你刷新页面,但是如果参数不变那么他自动使用本地缓存,所以加上random使得每次请求参数都是变更的

var pics=new Array()
 var ids=new Array();
 var intros=new Array(); 
 var uids=new Array(); 
var clicks=new Array();
var comms=new Array();
                $.getJSON(
             'ajax_getpics.aspx',
              { pageIndex: <%=pageindex%>, PageSize: "200", random: Math.random() },

         function (data) {
 
             $.each(data, function (i, entry) {
            
               pics[i]=entry['orginpath'];
               ids[i]=entry["pic_id"];
               intros[i]=entry["description"];
               uids[i]=entry["user_id"];
               clicks[i]=entry["click"];
               comms[i]=entry["commpeople"];
               });

      //do detect
             

 

 瀑布页码代码,这个代码是在页码加载完毕后加载的,因为刚才说过需要增加单击图片时,弹出预览大图的效果,所以这里使用了highslide插件

因此代码里增加了下图红色的标记

 // 页面加载初始创建
        create: function () {
            this.columnNumber = Math.floor(document.body.clientWidth / this.columnWidth);

            var start = 0, htmlColumn = '', self = this;
            for (start; start < this.columnNumber; start += 1) {
                htmlColumn = htmlColumn + '<span id="waterFallColumn_' + start + '" class="column" style="width:' + this.columnWidth + 'px;">' +
                function () {
                    var html = '', i = 0;
                    for (i = 0; i < 5; i += 1) {
                        self.indexImage = start + self.columnNumber * i;
                        var index = self.getIndex();
                        html = html + '   <a class="highslide pic_a" onclick="return hs.expand(this)" href='+index+'  ><img src=' + index+' /><strong>'+self.getIntro().substring(0,50)+'</strong>  <br> <span class=pro> '+self.getClick()+' click &nbsp;&nbsp;&nbsp;&nbsp; '+ self.getComm()+' comment </span> </a><div class="highslide-caption">'+self.getIntro()+' <a target=_blank href=userinfo.aspx?id='+self.getUid()+'>查看用户</a> |  <a  target=_blank href=picdetail.aspx?pid='+self.getId()+'>查看图片('+self.getClick()+')</a> </div> ';
                    }
                    return html;
                } () +
            '</span> ';
            }
            htmlColumn += '<span id="waterFallDetect" class="column" style="width:' + this.columnWidth + 'px;"></span>';

            this.container.innerHTML = htmlColumn;

            this.detectLeft = document.getElementById("waterFallDetect").offsetLeft;
            return this;
        },

 

 

当页码滚动时,动态加载图片

 

 

        // 滚动载入
        append: function (column) {
            this.indexImage += 1;
            var html = '',  index = this.getIndex(),  imgUrl = index;

            // 图片尺寸
            var aEle = document.createElement("div");
           
            aEle.className = "pic_a";
            aEle.innerHTML = ' <a class="highslide pic_a" onclick="return hs.expand(this)" href='+imgUrl+'><img src=' + imgUrl + ' /><strong>'+this.getIntro()+'</strong></a>';
            column.appendChild(aEle);
             
            if (this.indexImage >= 200) {
                  this.loadFinish = true;
            }

            return this;
        },

 

这样,一个比较完成的例子就完成了。 下载源代码

posted @ 2012-07-19 09:49  启明星工作室  阅读(7034)  评论(5编辑  收藏  举报