最近基于jQuery和Bootstrap框架实现了一个仿知乎动态列表的前端效果,基本实现了和知乎动态列表相同的效果。如下:
1.基本列表项
2.列表项全文展开、折叠(图中为展开第一项)
3.评论项展开
4.列表数据加载(加载全部)
5.带动画效果的点赞功能
6.回复列表的hover显示功能
HTML代码如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" /> <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" /> <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css" /> <script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script> <script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> <script src="scripts/jquery.json.min.js"></script> <link rel="stylesheet" href="styles/main.css" /> <script src="scripts/test.js"></script> </head> <body> <div style="display:none;"> <div id="t_dn" class="dynamic_node"> <meta class="dn_id" content=""/> <meta class="dn_user_id" content=""/> <div class="dn_left"> <div class="dn_user_avatar"><a href=""> <img class="img-thumbnail" src="" /></a> </div> <div class="dn_zannum"> <span></span> </div> <div class="dn_dianzan"> <a href=""><span class="glyphicon glyphicon-thumbs-up" aria-hidden="true"></span></a> </div> </div> <div class="dn_right"> <div class="dn_title"> <span class="glyphicon glyphicon-share-alt" aria-hidden="true"></span> <a href=""><span></span></a> </div> <div class="dn_right_top"> <div class="dn_username"> <a href=""><span class="dn_username_name"></span></a> <span class="dn_username_signature"></span> </div> <div class="dn_content_close1"> <a href=""> <span class="glyphicon glyphicon-triangle-bottom" aria-hidden="true"></span> </a> </div> </div> <div class="dn_content"> <a href="" class="dn_content_link"> <span class="dn_content_digest"></span> </a> <span class="dn_content_text"></span> </div> <div class="dn_action"> <div class="dn_content_close2"> <a href=""> <span class="glyphicon glyphicon-triangle-top" aria-hidden="true"></span> </a> </div> <a href=""><span class="dn_action_report">举报</span></a> <a href=""><span class="dn_action_share">分享</span></a> <a href=""><span class="dn_action_comm">103条评论</span></a> <span class="dn_action_time"></span> </div> <div class="dn_comm"> <div class="dn_comm_items"> </div> <div class="dn_comm_showall"> <button id="dn_comm_showall_button" type="button" class="btn btn-default btn-xs">显示全部评论</button> </div> <div class="dn_comm_replay"> <div class="dn_comm_replay_field"> <textarea class="form-control" rows="2" placeholder="写下你的评论..."></textarea> </div> <div class="dn_comm_replay_buttoms"> <button type="button" class="btn btn-primary btn-sm">评论</button> <a href="" class="dn_comm_replay_buttoms_cancel">取消</a> </div> </div> </div> </div> </div> <div id="t_dn_comm" class="dn_comm_item"> <meta class="dn_comm_id" content=""> <div class="dn_comm_item_left"> <div> <a href="#"><img class="img-rounded" src="images/user.png" /> </a> </div> </div> <div class="dn_comm_item_mid"> <div class="dn_comm_item_middle_username"> <a href="#"><span>用户名</span></a> </div> <div class="dn_comm_item_mid_content"> <span></span> </div> <div class="dn_comm_foot"> <div class="dn_comm_foot_left"> <span>2015-09-08 12:00:09</span> </div> <div class="dn_comm_item_mid_action"> <a href="#"><span>回复</span></a> <a href="#"><span>举报</span></a> </div> </div> </div> <div class="dn_comm_item_right"> <div class="dn_comm_zannum"> <span>5</span> </div> <div class="dn_comm_dianzan"> <a href="#"> <span class="glyphicon glyphicon-thumbs-up" aria-hidden="true"></span> </a> </div> </div> </div> </div> <div class="global"> <div class="list_layout"> </div> <div class="load_flag"> <button id="load_flag_button" type="button" class="btn btn-default btn-s">加载更多</button> <div id="load_flag_info"><small>没有更多了 !</small></div> </div> </div> </body> </html>
css文件代码如下(main.css):
<style> /* global navigadion */ .nav{ width:100%; height:3.5em; padding-top:0em; vertical-align:middle; background-image: -moz-linear-gradient(top, #99FFFF, #FFFFFF); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #99FFFF), color-stop(1, #FFFFFF)); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#99FFFF', endColorstr='#FFFFFF', GradientType='0'); } .nav-content{ width:1024px; margin-left: auto; margin-right: auto; } #nav_user_name,#nav_user_avatar,#nav_btn_notice,#nav_btn_discuss,#nav_btn_read,#nav_btn_index,#nav_search_text,#nav_search_text{ margin-top:0.5em; } .brand{ font-size:2.5em; font-weight:lighter; color:#5e5e5e; font-family: "Microsoft JhengHei"! important; } .avatar img{ padding:0.2em; } #notice_num{ visibility:visible; backgroung-color:red; color:white; width: 1.6em; height: 1.6em; background: red; -moz-border-radius: 1em; -webkit-border-radius: 1em; border-radius: 1em; position:fixed; } #nav_user_name{ float:right; } #nav_user_avatar{ float:right; } .content{ width:1024px; margin-left: auto; margin-right: auto; } .left{ float:left; width:100%; } .right{ background-color:white; float:left; width:100%; } .foot{ float:left; } .foot span{ font-size:0.8em; font-weight:lighter; } .dashed-line{ border-bottom:1px dashed; border-bottom-color:#C9C9C9; } /*##############################################*/ /* dynamic list */ .dynamic_node{ width:100%; border-top:1px solid #eee; padding-bottom:1em; padding-top:1em; float:left; } .dn_left{ width:50px; float:left; } .dn_left img{ width:50px; height:50px; } .dn_dianzan,.dn_zannum{ width:100%; float:left; margin-left:auto; margin-right:auto; text-align:center; } .dn_right{ padding-left:1em; width:666px; float:left; } .dn_title label{ font-weight:lighter; color:#6b6b6b; } .dn_title a span{ color:#259; font-weight:bold; } .dn_username_name{ font-weight:bold; font-size:0.8em; color:#259; } .dn_username_signature{ font-size:0.8em; } .dn_action{ float:right; } .dn_action span{ float:right; margin-left:1em; margin-top:1em; font-size:0.8em; } .dn_content_digest,.dn_content_text{ float:left; font-size:0.8em; color:#363636; width:100%; } .dn_content_text{ display:none; } .dn_content_close1,.dn_content_close2{ float:right; display:none; font-size:1em; } .dn_action{ display:none; float:right; } .dn_comm{ float:left; width:100%; display:none; } .dn_comm_items{ float:left; width:100%; } .dn_comm_item{ float:left; margin-top:0.8em; border-top:1px solid #eee; padding-top:0.8em; } .dn_comm_item_left{ width:50px; float:left; } .dn_comm_item_mid{ width:560px; float:left; } .dn_right_top{ width:100%; float:left; } .dn_comm_item_right{ width:30px; float:right; text-align:center; } .dn_comm_item_left img{ width:30px; height:30px; } .dn_comm_item_middle_username,.dn_comm_item_mid_content,.dn_comm_item_mid_time{ float:left; font-size:0.8em; } .dn_comm_item_mid_action{ float:right; margin-left:1em; font-size:0.8em; display:none; } .dn_comm_item_mid_action span{ margin-left:1em; } .dn_comm_dianzan{ font-size:1em; width:100%; margin-left:auto; margin-right:auto; } .dn_comm_zannum{ font-size:1em; color:#797979; width:100%; margin-left:auto; margin-right:auto; } .dn_comm_foot_left{ float:left; padding-top:0.4em; color:#797979; width:50%; font-size:0.7em; } .dn_comm_replay{ float:left; width:100%; margin-top:1em; padding-top:1em; border-top:1px solid #eee; } .dn_comm_replay_field{ float:left; width:100%; margin-bottom:1em; } .dn_comm_replay_buttoms a,button{ float:right; } .dn_comm_replay_buttoms_cancel{ padding-top:0.5em; margin-right:1em; } .dn_comm_dianzan{ width:100%; float:left; } .dn_comm_showall{ float:left; width:100%; margin-top:1em; padding-top:1em; border-top:1px solid #eee; } .dn_comm_showall #dn_comm_showall_button{ float:left; width:80%; margin-left:10%; margin-right:10%; margin-top:1em; border-top:1px solid #eee; } /*##############################################*/ /* */ .global{ width:716px; } .list_layout,.load_flag{ width:100%; float:left; display:block; } .load_flag{ padding-top:1em; border-top:1px solid #eee; margin-bottom:3em; } .load_flag button{ float:left; width:80%; margin-left:10%; margin-right:10%; } .load_flag #load_flag_info{ float:left; text-align:center; width:80%; margin-left:10%; margin-right:10%; display:none; } /*##############################################*/ /* */ </style> js文件内容如下(test.js): [javascript] view plain copy $(document).ready(function(){ url_user = "http://user.com/i="; url_img = "http://127.0.0.1/pages/"; url_dianzan = "http://dianzan.com"; url_dn_detail = "http://dt.com/i="; layout_list = $(".list_layout"); t_dn = $("#t_dn"); t_dn_comm = $("#t_dn_comm"); maxnum = 2; // 最大加载次数 num = 1; load_flag = $(".load_flag"); function render_dn_list(arr_dn){ for(var i=0; i<arr_dn.length;i++){ var node_dn = t_dn.clone(); node_dn.find(".dn_id").attr("content",arr_dn[i]["ID"]); //动态ID node_dn.find(".user_id").attr("content",arr_dn[i]["userid"]); //用户ID node_dn.find(".dn_left .dn_user_avatar a").attr("href",url_user+arr_dn[i]["userid"]); // 用户名链接 node_dn.find(".dn_left .dn_user_avatar a img").attr("src",url_img+arr_dn[i]["avatar"]); // 用户头像 node_dn.find(".dn_zannum span").text(arr_dn[i]["zan"]); // 点赞数 //node_dn.find(".dn_dianzan a").attr("href",arr_dn[i]["avatar"]); // 点赞链接 node_dn.find(".dn_title a").attr("href",url_dn_detail+arr_dn[i]["fid"]+"#"+arr_dn[i]["ID"]); //跳转动态所在页锚点 node_dn.find(".dn_title a span").text(arr_dn[i]["from"]); // 所属标题 node_dn.find(".dn_username a").attr("src",url_user+arr_dn[i]["userid"]); //用户名链接 node_dn.find(".dn_username_name").text(arr_dn[i]["username"]); //用户名 node_dn.find(".dn_username_signature").text(arr_dn[i]["signature"]); //用户签名 var digest = ""; var content = arr_dn[i]["content"]; if(content.length > 150){ digest=content.substring(0,150)+"... "; } else{ digest=content; } node_dn.find(".dn_content_digest").text(digest); //摘要 node_dn.find(".dn_content_digest").append("<a href='#'> 显示全部</a>"); node_dn.find(".dn_content_text").text(content); // 正文 node_dn.find(".dn_action_time").text(arr_dn[i]["posttime"]); // 发布时间 // 添加点击摘要事件 node_dn.find(".dn_content_digest").click( function(){ var dn_right = $(this).parent().parent().parent(); dn_right.find(".dn_content_text").toggle(); dn_right.find(".dn_content_digest").toggle(); dn_right.parent().find(".dn_content_close1").toggle(); dn_right.parent().find(".dn_content_close2").toggle(); dn_right.parent().find(".dn_action").toggle(); var comm= dn_right.find(".dn_comm"); if(comm.css("display") == "block"){ comm.css("display","none"); } return false; // !! } ); // 添加点击折叠事件 node_dn.find(".dn_content_close2,.dn_content_close1").click( function(){ var dn_right = $(this).parent().parent(); dn_right.find(".dn_content_text").toggle(); dn_right.find(".dn_content_digest").toggle(); dn_right.parent().find(".dn_content_close1").toggle(); dn_right.parent().find(".dn_content_close2").toggle(); dn_right.parent().find(".dn_action").toggle(); var comm= dn_right.find(".dn_comm"); if(comm.css("display") == "block"){ comm.css("display","none"); } return false; // !! } ); // 为评论、分享、举报按钮添加hover下划线效果 node_dn.find(".dn_action_comm,.dn_action_share,.dn_action_report").hover( function(){ $(this).css("text-decoration","underline"); return false; // !! } , function(){ $(this).css("text-decoration","none"); return false; // !! } ); // 为列表项添加点赞事件 node_dn.find(".dn_dianzan").click( function(){ //alert('zan'); var dn_left = $(this).parent(); var zan_num = dn_left.find(".dn_zannum span"); var currzan = zan_num.text(); zan_num.text(parseInt(currzan)+1); zan_num.animate({fontSize:"1.2em"},"fast"); $(this).animate({fontSize:"1.2em"},"fast"); zan_num.animate({fontSize:"1em"},"fast"); $(this).animate({fontSize:"1em"},"fast"); return false; // !! } ); // 加载评论,并处理评论项事件 function load_comm(dn_id,dn_comm_items,flag){ var load_url = "mockdata/commdata_"; if(flag == 1){ load_url = "mockdata/commdata_"; } else{ load_url = "mockdata/commdata_"; } $.ajax({ url:"mockdata/commdata_"+dn_id, type: "get",//使用get方法访问后台 dataType: "json",//返回json格式的数据 async:false, //data: "pageIndex=" + pageIndex,//要发送的数据 complete :function(){$("#load").hide();},//AJAX请求完成时隐藏loading提示 success: function(msg){//msg为返回的数据,在这里做数据绑定 var encoded = $.toJSON(msg); ret_code =$.evalJSON(encoded).code; arr_dn =$.evalJSON(encoded).data; if(ret_code == "200"){ for(var i=0;i<arr_dn.length;i++){ var n_comm = t_dn_comm.clone(); n_comm.find(".dn_comm_id").attr("content",arr_dn[i]["ID"]); n_comm.find(".dn_comm_item_left a").attr("href",url_user+arr_dn[i]["userid"]); n_comm.find(".dn_comm_item_left img").attr("content",url_img+arr_dn[i]["avatar"]); n_comm.find(".dn_comm_item_middle_username a").attr("href",url_user+arr_dn[i]["userid"]); n_comm.find(".dn_comm_item_middle_username a span").text(arr_dn[i]["username"]); n_comm.find(".dn_comm_item_mid_content span").text(arr_dn[i]["content"]); n_comm.find(".dn_comm_foot_left span").text(arr_dn[i]["posttime"]); n_comm.find(".dn_comm_zannum span").text(arr_dn[i]["zan"]); // 为评论项添加hover效果 n_comm.hover(function(){ $(this).find(".dn_comm_item_mid_action").toggle(); }); // 为评论项添加点赞动画效果 var zan = n_comm.find(".dn_comm_dianzan"); zan.click( function(){ var zan_num = $(this).parent().find(".dn_comm_zannum"); var currzan = zan_num.text(); zan_num.text(parseInt(currzan)+1); zan_num.animate({fontSize:"1.2em"},"fast"); $(this).animate({fontSize:"1.2em"},"fast"); zan_num.animate({fontSize:"1em"},"fast"); $(this).animate({fontSize:"1em"},"fast"); return false; } ); dn_comm_items.append(n_comm); } } else{ alert(ret_code); } } }); }; // 加载某一项的热门评论 node_dn.find(".dn_action_comm").click( function(){ var dn = $(this).parent().parent().parent().parent(); dn.find(".dn_comm").toggle(); var dn_comm_items = dn.find(".dn_comm_items"); dn_comm_items.empty(); var dn_id = dn.find(".dn_id").attr("content"); load_comm(dn_id,dn_comm_items,0); return false; // !! } ); // 加载某一项的全部评论 node_dn.find(".dn_comm_showall_button").click( function(){ var dn = $(this).parent().parent().parent().parent(); var dn_comm_items = dn.find(".dn_comm_items"); dn_comm_items.empty(); var dn_id = dn.find(".dn_id").attr("content"); load_comm(dn_id,dn_comm_items,1); return false; // !! } ); // layout_list.append(node_dn); } } function fill_list(){ $.ajax({ url:"mockdata/listdata", type: "get",//使用get方法访问后台 dataType: "json",//返回json格式的数据 async:false, //data: "pageIndex=" + pageIndex,//要发送的数据 complete :function(){$("#load").hide();},//AJAX请求完成时隐藏loading提示 success: function(msg){//msg为返回的数据,在这里做数据绑定 var encoded = $.toJSON(msg); ret_code =$.evalJSON(encoded).code; arr_dn =$.evalJSON(encoded).data; if(ret_code == "200"){ render_dn_list(arr_dn); } else{ alert(ret_code); } } }); } // 为加载数据按钮注册事件 $(".load_flag").click(function(){ if(num <= maxnum){ fill_list(); num++; } else{ load_flag.find("#load_flag_info").css("display","block"); load_flag.find("#load_flag_button").css("display","none"); } }); fill_list(); });
伪造的列表数据格式:
{ "code":"200", "data":[ { "ID":"1", "fid":"1212", "userid":"1001", "avatar":"images/user.png", "type":"阅读注解", "from":"金刚经/第一品 法会因由分", "username":"用户名", "signature":"用户个性签名", "digest":"内容摘要内容摘。要内容摘要,要内容要内容", "content":"时长老须菩提。在大众中。即从座起。偏袒右肩。右膝着地。合掌恭敬。而白佛言。希有世尊。如来善护念诸菩萨。善付嘱诸菩萨。世尊。善男子。善女人。发阿耨多罗三藐三菩提心。应云何住,云何降伏其心。佛言。善哉善哉。须菩提。如汝所说。如来善护念诸菩萨。善付嘱诸菩萨。汝今谛听。当为汝说。善男子。善女人。发阿耨多罗三藐三菩提心。应如是住,如是降伏其心。唯然。世尊。愿乐欲闻。", "posttime":"2015-09-08 12:00:09", "zan":"100" }, { "ID":"3", "fid":"1212", "userid":"1001", "avatar":"images/user.png", "type":"阅读注解", "from":"金刚经/第一品 法会因由分", "username":"用户名", "signature":"用户个性签名", "digest":"内容摘要内容摘。要内容摘要,要内容要内容", "content":"不于一佛二佛三四五佛而种善根。已于无量千万佛所种诸善根。闻是章句。乃至一念生净信者。须菩提。如来悉知悉见。是诸众生。得如是无量福德。何以故。是诸众生无复我相。人相。众生相。寿者相。无法相。亦无非法相。何以故。是诸众生。若心取相。则为著我人众生寿者。若取法相。即著我人众生寿者。何以故。若取非法相,即著我人众生寿者。是故不应取法。不应取非法。", "posttime":"2015-09-08 12:00:09", "zan":"100" },
伪造的评论数据格式:
{ "code":"200", "data":[ { "ID":"100001", "fid":"1212", "userid":"1001", "avatar":"images/user.png", "username":"用户名", "content":"时长老须菩提。善付嘱诸菩萨。汝今谛听。当为汝说。善男应如是住,如是降伏其心。唯然。世尊。愿乐欲闻。", "posttime":"2015-09-08 12:00:09", "zan":"100" }, { "ID":"100001", "fid":"1212", "userid":"1001", "avatar":"images/user.png", "username":"用户名", "content":"时长老须菩提。善付嘱诸菩萨。汝今谛听。当为汝说。善男应如是住,如是降伏其心。唯然。世尊。愿乐欲闻。", "posttime":"2015-09-08 12:00:09", "zan":"100" },