我们需要达成的功能点如下:
前端样式部分建立在 amazeUI
基础上,如使用请先引入相关CSS与JS
CSS与JS的引入我使用的是 BootCDN
作为CDN加速:
<link href="https://cdn.bootcss.com/amazeui/2.7.2/css/amazeui.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/amazeui/2.7.2/js/amazeui.min.js">script>
同样使用 Thymeleaf
作为模板,首先在html标签中引入Thymeleaf
xmlns:th="http://www.thymeleaf.org"
之后利用Thymeleaf
中的判断语句来判断游客状态:
th:if="${#httpServletRequest.remoteUser}
在后台,通过安全认证后,利用HttpServletRequest
接口类中的getRemoteUser()
方法可以获取到用户名
而在前端同样可以利用 remoteUser
来判断用户是否登录,具体实现代码:
<div th:unless="${#httpServletRequest.remoteUser}" id="comment-init-text">哼,不<a href="/login">登录a>就想对我指指点点,白嫖吗!div>
<textarea th:if="${#httpServletRequest.remoteUser}" maxlength="500" id="comment-text" class="am-modal-prompt-input private-conversation" placeholder="畅所欲言叭,骚年d(`・∀・)b!">textarea>
th:if
在Thymeleaf
语法中表示判断,如果 remoteUser
存在,则显示该标签,而th:unless
作用正好相反。
这样,如果用户处于游客状态(未登录),就只会显示第一个标签(div),使用户登录,如果用户已经登录,则显示第二个标签。
这里我将评论区获取的ajax封装为一个函数,方便调用:
function getComment() {
$.ajax(
{
type:"post",
url:"/getArticleComment",
dataType:"json",
async: false,
data:{
articleId: $("#articleId").val()
},
success:function(data){
var commentStr = "";
if(data['msg']=="empty") {
$(".article-comment-nonpeople").css("display", "block");
$(".article-comment-list-ol").html(commentStr);
selfIdEnd = 0;
} else {
$(".article-comment-nonpeople").css("display", "none");
selfIdEnd = data['data']['comment'][0]['selfId'];
$.each(data['data']['comment'],function(index,obj){
var commentStrUnit = "";
commentStrUnit += '\n' +
' \n' +
' \n' +
' + obj['commentImg'] +'" />\n' +
' \n' +
' \n' +
' + obj['selfId'] +'">'+ obj['respondentName'] +'\n' +
' #'+ obj['selfId'] +'楼\n' +
' '+ obj['date'] +'\n' +
' \n' +
obj['content'] +
' \n' +
' \n' +
' + obj['selfId'] +'">回复\n' +
' ['selfId'] +'">\n' obj+
' ['selfId'] +'">'+ obj['like'] +'\n' obj+
' \n' +
'\n' +
' \n'+
' \n' +
' \n' +
' \n' +
' +
obj['selfId'] +'">\n';
$.each(obj['reply'],function(index, obj2){
commentStrUnit +=
' \n' +
' \n' +
' \n' +
' + obj2['commentImg'] +'" />\n' +
' \n' +
' \n' +
' + obj['selfId'] + '-' + obj2['selfId'] +'">'+ obj2['respondentName'] +'\n' +
' '+ obj2['date'] +'\n' +
' \n' +
' @'+ obj2['answerName'] +'\n' +
' '+ obj2['content'] +'\n' +
' \n' +
' \n' +
' + obj['selfId'] + '-' + obj2['selfId'] +'">回复\n' +
' ['selfId'] + '-' + obj2['selfId'] +'" style="margin-right: 410px !important;">\n' obj+
' ['selfId'] + '-' + obj2['selfId'] +'">'+ obj2['like'] +'\n' obj+
' \n' +
' \n'+
' \n' +
' \n' +
' \n' +
' ' +
' \n';
});
commentStrUnit += ' \n' +
' \n' +
' ' +
' ';
commentStr += commentStrUnit;
});
$(".article-comment-list-ol").html(commentStr);
if(data['data']['likeList'] != "noLogin") {
$.each(data['data']['likeList'],function(index, obj) {
if(obj.split(",").length != 1) {
var likeHeart = "#comment-reply-like-heart-" + obj.split(",")[0] + "-" + obj.split(",")[1];
} else {
var likeHeart = "#comment-reply-like-heart-" + obj;
}
$(likeHeart).addClass("comment-reply-like-heart2");
});
}
}
},
error:function(){
console.log("评论显示失败!");
}
});
}
这样,只要在JS里直接调用getComment()
函数,即可显示评论区
$("#comment-btn").click(function () {
if(loginCheck==1) {
window.location.href = "/login";
} else {
if($("#comment-text").val()=="") {
alert("嘿,你还麻油输入评论内容捏(=m=)!")
} else {
var selfIdFinal = parseInt(selfIdEnd) + 1;
$.ajax(
{
type:"post",
url:"/insertComment",
dataType:"json",
async: false,
data:{
articleId: $("#articleId").val(),
selfId: selfIdFinal,
answerName: "Seaguller",
content: $("#comment-text").val()
},
success:function(data){
if(data['msg']=="noLogin") {
window.location.href = "/login";
}else if(data['msg']=="success") {
$(".article-comment-nonpeople").css("display", "none");
getComment();
$("#comment-text").val("");
}
},
error:function(){
console.log("评论插入失败!");
}
});
}
}
});
评论插入其实就是和后端交互后重新调用getComment()
函数,这样重新获取评论区的数据实现了实时插入与评论区的动态刷新。
评论回复主要在于两点:如何实现回复框在同一时间仅出现一个以及回复后评论区实时显示。
评论区实时显示这个并不难,我们上面评论插入中已经提到,因为把获取评论区内容的ajax请求封装为了一个函数,所以当我们点击回复按钮后,重新调用一下getComment()
函数,即可做到实时显示效果,代码如下:
/* 发表回复 */
$(".article-comment-list-ol").on("click", ".comment-reply-btn-right", function () {
var selfIdSplit = $(this).prev().attr("id").split("-");
if (selfIdSplit.length == 5) {
var selfIdOl = $("#article-comment-list-ol-" + selfIdSplit[selfIdSplit.length-1]);
var selfIdLiCount = selfIdOl.children("li").length + 1;
var selfIdFinal = selfIdSplit[selfIdSplit.length-1] + "," + selfIdLiCount;
var answerNameReplyFloor = selfIdSplit[selfIdSplit.length-1];
} else {
var selfIdOl = $("#article-comment-list-ol-" + selfIdSplit[selfIdSplit.length-2]);
var selfIdLiCount = selfIdOl.children("li").length + 1;
var selfIdFinal = selfIdSplit[selfIdSplit.length-2] + "," + selfIdLiCount;
var answerNameReplyFloor = selfIdSplit[selfIdSplit.length-2] + "-" + selfIdSplit[selfIdSplit.length-1];
}
if($("#comment-reply-text-" + answerNameReplyFloor).val()=="") {
alert("嘿,你还麻油输入回复内容捏(=m=)!");
console.log("reply: " + answerNameReplyFloor);
} else {
var answerNameReply = $("#comment-right-name-" + answerNameReplyFloor).html();
$.ajax(
{
type:"post",
url:"/insertComment",
dataType:"json",
async: false,
data:{
articleId: $("#articleId").val(),
selfId: selfIdFinal,
answerName: answerNameReply,
content: $("#comment-reply-text-" + answerNameReplyFloor).val()
},
success:function(data){
if(data['msg']=="noLogin") {
window.location.href = "/login";
}else if(data['msg']=="success") {
$("#comment-reply-text-" + answerNameReplyFloor).val("");
getComment();
}
},
error:function(){
alert("评论插入失败!");
}
});
}
});
上面以selfId
开头的变量是判断回复层数的,具体的方法主要是后端处理,这个会在后端讲到。
回复框设置的思想其实也是将回复框打开和关闭封装为一个函数:
/* 回复框框 */
function rep(num, flag) {
var strRepId = "#comment-reply-squ-" + num;
if(flag=="open") {
$(".comment-reply-squ").css("display", "none");
$(strRepId).css("display", "block");
} else if(flag=="close") {
$(strRepId).css("display", "none");
}
}
传参中num
表示楼数,而flag
表示显示/隐藏
每一个回复框预先都是设置为隐藏的,当调用这个函数时,传入对应回复的楼数和显示/关闭,即可控制对应的回复框。
(比如第七楼的第二个回复,他的ID就是comment-reply-squ-7-2
,如果要其显示,调用函数时只要传入7-2
和open
即可)
而因为每一个回复框的class
都是comment-reply-squ
所以,只要在open
的选择判断中将class
为comment-reply-squ
的display
属性设置为none
,即可隐藏所有的回复框,再将传入的指定回复框(用户所点击的)显示,即可做到同一时间仅有一个回复框显示。
on
来进行,否则获取不到,详见文章 关于jQuery获取不到动态添加的元素节点的问题textarea
)的字数限制避免评论字数过长导致页面布局混乱。7-2
,而不能是72
(我一开始中间就没加-
,后来导致第1楼第1个回复11
和第11楼一样嘞)