在web页面设计中,留言是个很常用的功能。根据设计需求,留言又可以分成简单留言和可回复(即可盖楼)留言。下面根据我在具体项目中的使用介绍这两种留言的实现方式。
1.简单留言
图1
简单评论如上图所示,不需要具备回复功能,上图页面地址:简单留言板。这个留言是使用js动态加载的。
html代码如下:
<textarea id="dome" class="commentArea"></textarea>
<div class="addMessageBtn">发布</div>
<div style="clear: both;"></div>
<ul class="commentList"></ul>
js代码如下:
getOnePageMessage(id ,messagePage);
function getOnePageMessage(id, page){
var onePageMessageTmp;
var messagePageCount;
isLoading = false;
$.ajax({
url : serverPrefix + "/wbLeaveMessage/getLeaveMessage",
type : "get",
dataType: "json",
data: {
wbId: id,
messageType: 1,
page: page,
pageSize: 10
},
success : function (data) {
if (data.code == 0){
messagePageCount = data.result.pageCount;
onePageMessageTmp = data.result.leaveMessages;
if ((onePageMessageTmp.length == 0) || (messagePageCount == 1)) { // 无数据或只有一页数据,隐藏加载提示
$("#loading").hide();
}
if (onePageMessageTmp.length != 0) {
addMessage(onePageMessageTmp);
isLoading = true;
}
}
else{
onePageMessageTmp.length = 0;
$("#loading").hide();
}
}
});
}
function addMessage(leaveMessages){ var template = ""; var html = ""; for (var i = 0; i < leaveMessages.length; i++){ template = '<li class="item" id="{id}">'; template += ' <div class="pic">'; template += ' <img src="http://images.v2gogo.com/{headImgUrl}">'; // 用户头像 template += ' </div>'; template += ' <div class="info">'; template += ' <div class="name">{fullname}</div>'; template += ' <div class="time">{createTime}</div>'; template += ' <div class="content">{content}</div>'; template += ' <div class="userName" style="display: none">{username}</div>'; template += ' </div>'; template += '</li>'; var timestamp = leaveMessages[i].createTime; // 时间戳设置为北京时间 leaveMessages[i].createTime = formatDate(timestamp); var userimg = leaveMessages[i].headImgUrl; // 如果headImgUrl等于null,替换为默认路径 if (userimg == null){ leaveMessages[i].headImgUrl = "headPortrait/default_head_img.png"; } html = template.formatString(leaveMessages[i]); $(".commentList").append(html); } }
上面的代码不算很复杂,思路就是先通过getOnePageMessage()函数从服务端获取到历史评论数据,在ajax通信的success函数里,调用addMessage()函数,addMessage()函数就是一个js模板,关于js模板动态加载页面内容的详细介绍,请见我的另外一篇博客:通过js和模板动态加载html页面。
对于这个简单评论,还有一个难点就是CSS该如何写?才能达到图1中的效果。下面给出CSS代码。
.commentList li:first-child { border-top: 1px solid #eee; } .commentList .item { font-size: 1rem; } .commentList li { position: relative; border-bottom: 1px solid #eee; padding: 10px 0; } .item { text-align: left; cursor: pointer; } li { display: list-item; }
.item .pic { float: left; margin-right: 10px; } div, a, p, ul, li, img, span { margin: 0; padding: 0; border: 0; }
.item .info { overflow: hidden; }
.commentList .name { float: left; }
.commentList .time { float: right; color: #666; }
.commentList .content { clear: both; color: #666; width: 100%; font-size: 1.5rem; display: inline-block; line-height: 28px; }
2.可盖楼留言
图2
可盖楼评论如图2所示。实现方式大部分和简单评论中的一样,唯一不同的是从服务端返回的数据中有了源评论这个字段,需要在js模板中添加对源评论拼接字符串的代码。下面只给出不同的代码。
js代码如下:
/**
* 添加评论列表,带盖楼功能(即源评论)
* @param list 评论列表
* @param parent html模板要加载到的父级元素
* @param pullDirection 加载方式。“up”:对应上拉评论动作,加载在父元素后面;“down”:对应下拉评论动作,加载在父元素前面
*/
function addComment(list, parent, pullDirection) {
var template = "";
var html = "";
var innerTemplate = "";
var innerHtml = "";
var buttonTemplate = "";
template = '<li class="item" id="{id}">'; // 评论模板
template += ' <div class="pic">';
template += ' <img src="'+ imagesPrefix +'{userimg}">';
template += ' </div>';
template += ' <div class="info">';
template += ' <div class="name">{fullname}</div>';
template += ' <div class="time">{createtime}</div>';
template += ' <div id="src-comment-{id}" class="src-comment"></div>';
template += ' <div class="content">{content}</div>';
template += ' <div id="small-img-{id}" class="small-img"></div>';
template += ' </div>';
template += '</li>';
$(list).each(function (i) { // 加载评论
var item = list[i];
var timestamp =item.createtime; // 时间戳设置为北京时间
item.createtime = formatDate(timestamp);
var userimg = item.userimg; // 如果headImgUrl等于null,替换为默认路径
if (userimg == null){
item.userimg = "headPortrait/default_head_img.png";
}
html += template.formatString(item);
});
if (pullDirection == "up") {
$(parent).append(html);
}
else {
$(parent).prepend(html);
}
// if ($(parent).attr("class") == "direct-broadcast-list") { // 如果是直播间列表,需要在列表中添加“上榜”、“置顶”按钮
// buttonTemplate = '<div class="btn setToppestAlways">置顶</div>';
// buttonTemplate += '<div class="btn setToppestOnce">上榜</div>';
// $(parent).find(".name").after(buttonTemplate);
// }
$(list).each(function (i) { // 加载源评论
var srcContent = list[i].srcContent;
var commentId = list[i].id;
if (srcContent != null) {
innerHtml = "";
$(srcContent).each(function (j) {
innerTemplate = '<li class="inner-item">'; // 源评论模板
innerTemplate += ' <div class="inner-name">{name}</div>';
innerTemplate += ' <div class="floor-num">' + parseInt(j + 1) + '楼</div>';
innerTemplate += ' <div class="inner-content">{content}</div>';
innerTemplate += '</li>';
innerHtml += innerTemplate.formatString(srcContent[j]);
});
$("#src-comment-" + commentId).html(innerHtml);
}
if (list[i].imgs != null) {
var imgSrc = imagesPrefix + list[i].imgs[0];
$("#small-img-" + commentId).html('<img src="'+ imgSrc +'">');
}
});
}
/**
* 字符串格式化,用于在模板中注入值
* 例:var s = "id={id}".formatString(obj);
* @param obj 对象
* @returns {string} 注入后的字符串
*/
String.prototype.formatString = function (obj) {
var reg = /{([^{}]+)}/gm;
return this.replace(reg, function (match, name) {
return obj[name];
});
}