博客項目實現文章評論功能(重點是評論回覆)

我開發的博客網站的地址:http://118.89.29.170/RiXiang_blog/javascript

博客項目代碼github:https://github.com/SonnAdolf/sonne_bloghtml

有了個人已成型的項目和代碼,能夠更容易理解這篇文章。前端

 

本篇文章記錄下本身博客項目評論功能實現的全過程,重點實際上是評論回覆功能。java

 

【一,寫評論】node

寫評論部分我沒有使用富文本編輯器,只是單純地使用了textarea標籤,因此後臺不須要做html標籤的白名單檢驗(關於防範xss攻擊,能夠看我以前的一篇文章http://www.cnblogs.com/rixiang/p/6239464.html),只須要將全部<和>字符做轉義便可。git

提交到後臺須要作的處理:必要的校驗,存儲。而後生成消息。消息會在用戶我的空間消息中心顯示。提示用戶有新的評論。github

數據庫存儲方面,評論與文章的關係是雙向多對一。設置懶加載和級聯刪除。數據庫

寫評論部分就這些,沒什麼好說的。數組

 

【二,評論顯示】app

評論的顯示是基於文章的。也就是說在點擊、查看一篇文章的同時,在該文章下面顯示對這篇文章的全部評論。

上面提到評論和文章是多對一的關係,可知,查詢到文章便可查詢到該文章的全部評論。也正所以,且鑑於本身博客評論數並不不少狀況,對於評論的分頁我沒有采用數據庫查詢層的分頁方法,而是用java寫了分頁、排序。我並不肯定最好的實現。

    /*
     * Select the article by the id, and show it at the jsp page.
     * 
     * @param HttpServletRequest request, Integer id, Model model
     * 
     * @return the jsp page
     */
    @RequestMapping(value = "/show", method = RequestMethod.GET)
    public String showFromMainPage(HttpServletRequest request, Integer id,
            Integer currentPage, Model model) throws Exception {
        if (null == id) {
            return "error";
        }
        Article article = articleService.find(id, Article.class);

        // click the link, then read_times ++
        article.setRead_times(article.getRead_times() + 1);
        articleService.update(article);

        article = getArticleOfContentByUrl(article);
        // sort the comments
        List<Comment> comments = commentService.sort(article.getComments());
        String username = userService.getUsernameFromSession(request);
        model.addAttribute("article", article);
        model.addAttribute("username", username);
        model.addAttribute("article_id", id);

        if (currentPage == null || currentPage <= 0) {
            currentPage = 1;
        }
        int totalSize = comments.size();
        PageInfo pageInfo = PageUtils.createPage(10, comments.size(),
                currentPage);
        int beginIndex = pageInfo.getBeginIndex();
        long totalNum = pageInfo.getTotalCount();
        int everyPage = pageInfo.getEveryPage();
        if (totalNum - beginIndex < everyPage) {
            comments = comments.subList(beginIndex, (int) totalNum);
        } else {
            comments = comments.subList(beginIndex, beginIndex + everyPage);
        }

        // 評論分頁
        Page<Comment> comments_page = new Page<Comment>(comments, totalSize,
                pageInfo);

        model.addAttribute("comments_page", comments_page);
        return "showArticlePage";
    }

以上代碼可看出,訪問文章路徑須要兩個參數,一個是文章id,一個是評論頁,相似這樣:http://118.89.29.170/RiXiang_blog/article/show.form?id=101&currentPage=2

根據id查詢文章Article article = articleService.find(id, Article.class);

而後獲取此文章的全部評論List<Comment> comments = commentService.sort(article.getComments());

以後即可以根據評論總數、每頁評論數、當前頁這三項信息來建立分頁類。關於分頁工具類,能夠看我以前總結的這篇文章http://www.cnblogs.com/rixiang/p/5257085.html

通常狀況下,分頁的邏輯要放在數據庫查詢層,而非java後臺的service和controller層,個人這個博客項目也實現了基於jpa的查詢分頁底層工具類。

 

【3、評論回覆功能實現】

評論回覆是本篇的重點。這部分我是參考博客園的邏輯實現的,效果是這樣:

以後我F12查看了下博客園的前端代碼,而後便有了思路了。

下面先寫下流程:

1,點擊文章下評論欄【回覆】連接後,調用javascript方法。

2,組合回覆內容:@usrname [quote]+引用內容+[/quote]做爲寫評論的<textarea>標籤的初始value。

3,用戶在二的基礎上寫了回覆後,點提交,數據庫會存儲帶有[quote]標籤的Comment內容,因爲是[]而不是<>因此不會由於xss跨站腳本校驗而被攔截。而後生成回覆的消息(用於通知被回覆用戶新消息)。

4,頁面顯示時,查詢到的數據庫中的Comment內容(帶有[quote]標籤的Comment內容),在前端顯示前用javascript做字符串轉化:

[quote]替換爲

<fieldset class="comment_quote">

         <legend>引用</legend>

         xxxxxxxx(引用的內容)

[/quote]替換爲</fieldset><br>

這樣便完成了html的拼接。顯示出來的將不是[quote][/quote],而是:


 

上述流程的第一二點的實現(quote拼接):

下面是基於jsp標籤的評論顯示:

                          <c:forEach items="${comments_page.content}" var="comment">
                                <div class="comment_box">
                                    <span class = "date">#${comment.floor}樓  &nbsp${fn:substring(comment.date,0,16)}</span> &nbsp&nbsp<span class = "author">${comment.authorName}</span>&nbsp&nbsp&nbsp&nbsp<a href="javascript:void(0)" onclick="quote_comment('${comment.content}','${comment.authorName}')">回覆</a><br> 
                                     <p class = "comment_content">${comment.content}</p>
                                </div>                          
                          </c:forEach>

【<a href="javascript:void(0)" onclick="quote_comment('${comment.content}','${comment.authorName}')">回覆</a>】表示點擊【回覆】連接後,調用quote_comment(content, usr_name)這一javascript方法。注意點擊連接調用js方法的寫法。以及jsp標籤內容做爲js方法參數的寫法,裏面的單引號必定不能落下。

                function quote_comment(content, usr_name) {
                    quote_content = '@' + usr_name + ' [quote]' + content.trim() + '[/quote]';
                    document.getElementById("comment_txt").value = quote_content;
                    document.getElementsByTagName('body')[0].scrollTop=document.getElementsByTagName('body')[0].scrollHeight;
                }

上面代碼用於組裝@用戶名和[quote]標籤,document.getElementById("comment_txt").value = quote_content;這句用於給textarea(寫評論輸入框)賦值。

document.getElementsByTagName('body')[0].scrollTop=document.getElementsByTagName('body')[0].scrollHeight;表示跳轉至頁面最底端。(寫評論輸入框在頁面最底下)

 

上述流程的第三四點(回覆內容顯示部分):

   $(document).ready(function() { ......});

里加入這兩句(頁面初始化時候):

                  var comment_arr=getElementsClass("comment_content");
                  commentsQuoteTagReset(comment_arr);

首先調用方法function getElementsClass(classnames)獲取全部class屬性爲comment_content的內容,(上面貼的jsp代碼,<p class = "comment_content">${comment.content}</p>這句說明設置顯示評論內容的p標籤的class爲comment_content,而後咱們根據該class標籤作javascript dom操做):

             function getElementsClass(classnames){ 
                   var classobj= new Array(); 
                   //數組下標 
                   var classint=0;
                   //獲取HTML的全部標籤 
                   var tags=document.getElementsByTagName("*");
                   for(var i in tags){
                         if(tags[i].nodeType==1){
                              //判斷節點類型 
                              if(tags[i].getAttribute("class") == classnames)
                              { 
                                    classobj[classint]=tags[i]; 
                                    classint++; 
                               } 
                          } 
                    } 
                    return classobj;
               }

以後替換[quote]和[/quote]:

               function commentsQuoteTagReset(comment_arr) {
                   var str;
                   for(var i=0; i < comment_arr.length; i++) {
                        str = comment_arr[i].innerHTML;
                        str = str.replace(/\[quote]/g,"<fieldset class=\"comment_quote\"><legend>引用</legend>");
                        str = str.replace(/\[\/quote]/g,"</fieldset>");
                        comment_arr[i].innerHTML=str;
                   } 
               }

要注意javascript裏字符串替換沒有相似java replaceAll的寫法,replace的話只能替換查詢到的第一個。

須要這樣的寫法:

str = str.replace(/\aaa/g,'bbb');

comment_arr[i].innerHTML=str;寫法能夠替換對應的<p>標籤的內容。

這樣實現的效果即是:

 

 


 

以上です

主要講的是思路,加上一些我本身以爲有必要記錄的技術點。細節方面,若是基礎好的話,有了思路就能夠瞬間懂了。我就是f12看了博客園頁面而後瞬間有了思路。

 

最後貼幾張博客的圖片。這個博客功能基本都已實現,之後就是不斷優化了。

相關文章
相關標籤/搜索