thinkPHP实现基于ajax的评论回复功能

本文实例讲述了thinkPHP实现基于ajax的评论回复功能。分享给大家供大家参考,具体如下:

控制器代码:

<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
  public function index(){
    $num = M('comment')->count(); //获取评论总数
    $this->assign('num',$num);
    $data=array();
    $data=$this->getCommlist();//获取评论列表
    $this->assign("commlist",$data);
    $this->display('index');
  }
  /**
  *添加评论
  */
  public function addComment(){
    $data=array();
    if((isset($_POST["comment"]))&&(!empty($_POST["comment"]))){
      $cm = json_decode($_POST["comment"],true);//通过第二个参数true,将json字符串转化为键值对数组
      $cm['create_time']=date('Y-m-d H:i:s',time());
      $newcm = M('comment');
      $id = $newcm->add($cm);
      $cm["id"] = $id;
      $data = $cm;
      $num = M('comment')->count();//统计评论总数
      $data['num']= $num;
    }else{
      $data["error"] = "0";
    }
    echo json_encode($data);
  }
  /**
  *递归获取评论列表
  */
  protected function getCommlist($parent_id = 0,&$result = array()){
    $arr = M('comment')->where("parent_id = '".$parent_id."'")->order("create_time desc")->select();
    if(empty($arr)){
      return array();
    }
    foreach ($arr as $cm) {
      $thisArr=&$result[];
      $cm["children"] = $this->getCommlist($cm["id"],$thisArr);
      $thisArr = $cm;
    }
    return $result;
  }
}

JavaScript代码:

$(function(){
  //点击提交评论内容
  $('body').delegate('.comment-submit','click',function(){
    var content = $.trim($(this).parent().prev().children("textarea").val());//根据布局结构获取当前评论内容
    $(this).parent().prev().children("textarea").val("");//获取完内容后清空输入框
    if(""==content){
      alert("评论内容不能为空!");
    }else{
      var cmdata = new Object();
      cmdata.parent_id = $(this).attr("parent_id");//上级评论id
      cmdata.content = content;
      cmdata.nickname = "游客";//测试用数据
      cmdata.head_pic = "/Public/images/default.jpg";//测试用数据
      var replyswitch = $(this).attr("replyswitch");//获取回复开关锁属性
      $.ajax({
        type:"POST",
        url:"/index.php/home/index/addComment",
        data:{
          comment:JSON.stringify(cmdata)
        },
        dataType:"json",
        success:function(data){
          if(typeof(data.error)=="undefined"){
            $(".comment-reply").next().remove();//删除已存在的所有回复div
            //更新评论总数
            $(".comment-num").children("span").html(data.num+"条评论");
            //显示新增评论
            var newli = "";
            if(cmdata.parent_id == "0"){
             //发表的是一级评论时,添加到一级ul列表中
             newli = "<li comment_id='"+data.id+"'><div ><div><img class='head-pic' src='"+data.head_pic+"' alt=''></div><div class='cm'><div class='cm-header'><span>"+data.nickname+"</span><span>"+data.create_time+"</span></div><div class='cm-content'><p>"+data.content+"</p></div><div class='cm-footer'><a class='comment-reply' comment_id='"+data.id+"' href='javascript:void(0);'>回复</a></div></div></div><ul class='children'></ul></li>";
              $(".comment-ul").prepend(newli);
            }else{
             //否则添加到对应的孩子ul列表中
              if('off'==replyswitch){//检验出回复关闭锁存在,即三级评论不再提供回复功能
                newli = "<li comment_id='"+data.id+"'><div ><div><img class='head-pic' src='"+data.head_pic+"' alt=''></div><div class='children-cm'><div class='cm-header'><span>"+data.nickname+"</span><span>"+data.create_time+"</span></div><div class='cm-content'><p>"+data.content+"</p></div><div class='cm-footer'></div></div></div><ul class='children'></ul></li>";
              }else{//二级评论的回复按钮要添加回复关闭锁属性
                newli = "<li comment_id='"+data.id+"'><div ><div><img class='head-pic' src='"+data.head_pic+"' alt=''></div><div class='children-cm'><div class='cm-header'><span>"+data.nickname+"</span><span>"+data.create_time+"</span></div><div class='cm-content'><p>"+data.content+"</p></div><div class='cm-footer'><a class='comment-reply' comment_id='"+data.id+"' href='javascript:void(0);' replyswitch='off' >回复</a></div></div></div><ul class='children'></ul></li>";
              }
              $("li[comment_id='"+data.parent_id+"']").children("ul").prepend(newli);
            }
          }else{
            //有错误信息
            alert(data.error);
          }
        }
      });
    }
  });
  //点击"回复"按钮显示或隐藏回复输入框
  $("body").delegate(".comment-reply","click",function(){
    if($(this).next().length>0){//判断出回复div已经存在,去除掉
      $(this).next().remove();
     }else{//添加回复div
      $(".comment-reply").next().remove();//删除已存在的所有回复div
      //添加当前回复div
      var parent_id = $(this).attr("comment_id");//要回复的评论id
      var divhtml = "";
      if('off'==$(this).attr("replyswitch")){//二级评论回复后三级评论不再提供回复功能,将关闭属性附加到"提交回复"按钮"
        divhtml = "<div class='div-reply-txt' style='width:98%;padding:3px;' replyid='2'><div><textarea class='txt-reply' replyid='2' style='width: 100%; height: 60px;'></textarea></div><div style='margin-top:5px;text-align:right;'><a class='comment-submit' parent_id='"+parent_id+"' style='font-size:14px;text-decoration:none;background-color:#63B8FF;' href='javascript:void(0);' replyswitch='off' >提交回复</a></div></div>";
      }else{
        divhtml = "<div class='div-reply-txt' style='width:98%;padding:3px;' replyid='2'><div><textarea class='txt-reply' replyid='2' style='width: 100%; height: 60px;'></textarea></div><div style='margin-top:5px;text-align:right;'><a class='comment-submit' parent_id='"+parent_id+"' style='font-size:14px;text-decoration:none;background-color:#63B8FF;' href='javascript:void(0);'>提交回复</a></div></div>";
      }
      $(this).after(divhtml);
     }
  });
})

页面样式代码:

.comment-filed{
  width:640px;
  margin:0 auto;
}
.comment-num{
  text-align: right;
  font-size:14px;
}
.div-txt-submit{
  text-align:right;
  margin-top:8px;
}
.comment-submit{
  background-color:#63B8FF;
  margin-top:15px;
  text-decoration:none;
  color:#fff;
  padding:5px;
  font-size:14px;
}
.txt-commit{
  border:1px solid blue;
  width:620px;
  height: 60px;
  padding: 10px;
}
.txt-reply{
  width: 100%;
  height: 60px;
}
.comment-filed-list{
  margin-top:20px;
}
.comment-list{
  margin-top:2px;
  width:herit;
  height:50px;
  border-top:1px solid gray;
}
.comment-ul{
  list-style:none;
  padding-left:0;
}
.head-pic{
  width:40px;
  height:40px;
}
.cm{
  position:relative;
  top:0px;
  left:40px;
  top:-40px;
  width:600px;
}
.cm-header{
  padding-left:5px;
}
.cm-content{
  padding-left:5px;
}
.cm-footer{
  padding-bottom:15px;
  text-align:right;
  border-bottom: 1px dotted #CCC;
}
.comment-reply{
  text-decoration:none;
  color:gray;
  font-size: 14px;
}
.children{
  list-style:none;
  background-color:#FAFAFA;
  padding-left:0;
  margin-left:40px;
}
.children-cm{
  position:relative;
  left:40px;
  top:-40px;
  width:90%;
}

页面布局代码:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
  <title>php评论及回复功能</title>
  <link rel="stylesheet" type="text/css" href="/Public/css/comment.css" rel="external nofollow" >
  <script type="text/javascript" src="/Public/js/jquery-1.11.3.min.js" ></script>
  <script type="text/javascript" src="/Public/js/comment.js" ></script>
</head>
<body>
<div class="comment-filed">
 <!--发表评论区begin-->
 <div>
  <div class="comment-num">
    <span>{$num}条评论</span>
  </div>
  <div>
    <div>
    <textarea class="txt-commit" replyid="0"></textarea>
    </div>
    <div class="div-txt-submit">
      <a class="comment-submit" parent_id="0" style="" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><span style=''>发表评论</span></a>
    </div>
  </div>
 </div>
 <!--发表评论区end-->
 <!--评论列表显示区begin-->
  <!-- {$commentlist} -->
  <div class="comment-filed-list" >
    <div><span>全部评论</span></div>
    <div class="comment-list" >
      <!--一级评论列表begin-->
      <ul class="comment-ul">
        <volist name="commlist" id="data">
          <li comment_id="{$data.id}">
          <div >
            <div>
              <img class="head-pic" src="{$data.head_pic}" alt="">
            </div>
            <div class="cm">
              <div class="cm-header">
              <span>{$data.nickname}</span>
              <span>{$data.create_time}</span>
              </div>
              <div class="cm-content">
                <p>
                  {$data.content}
                </p>
              </div>
              <div class="cm-footer">
                <a class="comment-reply" comment_id="{$data.id}" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >回复</a>
              </div>
            </div>
          </div>
          <!--二级评论begin-->
          <ul class="children">
            <volist name="data.children" id="child" >
            <li comment_id="{$child.id}">
              <div >
                <div>
                  <img class="head-pic" src="{$child.head_pic}" alt="">
                </div>
                <div class="children-cm">
                  <div class="cm-header">
                  <span>{$child.nickname}</span>
                  <span>{$child.create_time}</span>
                  </div>
                  <div class="cm-content">
                    <p>
                      {$child.content}
                    </p>
                  </div>
                  <div class="cm-footer">
                    <a class="comment-reply" replyswitch="off" comment_id="{$child.id}" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >回复</a>
                  </div>
                </div>
              </div>
              <!--三级评论begin-->
              <ul class="children">
                <volist name="child.children" id="grandson" >
                <li comment_id="{$grandson.id}">
                  <div >
                    <div>
                      <img class="head-pic" src="{$grandson.head_pic}" alt="">
                    </div>
                    <div class="children-cm">
                      <div class="cm-header">
                      <span>{$grandson.nickname}</span>
                      <span>{$grandson.create_time}</span>
                      </div>
                      <div class="cm-content">
                        <p>
                          {$grandson.content}
                        </p>
                      </div>
                      <div class="cm-footer">
                        <!-- <a class="comment-reply" comment_id="1" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >回复</a> -->
                      </div>
                    </div>
                  </div>
                </li>
                </volist>
              </ul>
              <!--三级评论end-->
            </li>
            </volist>
          </ul>
          <!--二级评论end-->
        </li>
        </volist>
      </ul>
      <!--一级评论列表end-->
    </div>
  </div>
 <!--评论列表显示区end-->
</div>
</body>
</html>

sql语句:

DROP TABLE IF EXISTS `t_comment`;
CREATE TABLE `t_comment` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
 `parent_id` int(11) NOT NULL COMMENT '上级评论id,若是一级评论则为0',
 `nickname` varchar(100) DEFAULT NULL COMMENT '评论人昵称',
 `head_pic` varchar(400) DEFAULT NULL COMMENT '评论人头像',
 `content` text COMMENT '评论内容',
 `create_time` datetime DEFAULT NULL COMMENT '评论或回复发表时间',
 PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=148 DEFAULT CHARSET=utf8;

页面布局少一个jquery.js请自行加上。

更多关于thinkPHP相关内容感兴趣的读者可查看本站专题:《ThinkPHP入门教程》、《thinkPHP模板操作技巧总结》、《ThinkPHP常用方法总结》、《codeigniter入门教程》、《CI(CodeIgniter)框架进阶教程》、《Zend FrameWork框架入门教程》及《PHP模板技术总结》。

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

(0)

相关推荐

  • php无限级分类实现评论及回复功能

    经常在各大论坛或新闻板块详情页面下边看到评论功能,当然不单单是直接发表评论内容那么简单,可以对别人的评论进行回复,别人又可以对你的回复再次评论或回复,如此反复,理论上可以说是没有休止,从技术角度分析很容易想到运用无限级分类技术存储数据,运用递归获取评论层级结构数据,运用ajax实现评论页面交互,这里用thinkphp框架做个简单的demo练练手,为了简化流程这里第三级评论开始停止回复,当然只要在这个基础上稍作修改就可以实现无限回复功能,主要是view层样式修改较麻烦,需花些时间. 一.效果需求分

  • PHP仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(上)

    我们大部分人都发过动态,想必都知道发动态.回复评论.删除动态的整个过程,那么作为初学者,要模仿这些功能有点复杂的,最起码表的关系得弄清楚~~ 先把思路理一下: (1)用户登录,用session读取当前用户----目的是:该用户可以发表动态,重点是显示该用户好友及他自己发表的动态,并且按发表时间排序. (2)做个发表动态框实现发表动态功能 (3)显示该用户和他好友已经发表对的动态信息,并按发表时间由近到远显示 (4)再每条动态后面做一个评论按钮和删除按钮:实现对动态的评论,回复和删除(斜体部分下一

  • php模仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(中)

    在上一篇随笔中已经将如何发布动态呈现了,那么现在来看一下剩下的评论动态.回复评论.删除动态和评论功能,这几个功能会有点绕~~~ 一.思路如下: (1)你发表动态之后,会有人评论这一条动态,当评论之后,你也会回复该评论:(此处评论要单独一张表,回复也要单独一张表) (2)删除动态:会将动态连同评论.回复全部删除:删除评论:只会删除该条评论 二.在写代码之前,我还是想把流程说一遍: (1)发表动态---评论---回复---再回复 (2)将上边的流程细化,我先在纸上写出,再上传,码字不能表达清楚(注意

  • thinkPHP框架实现的无限回复评论功能示例

    本文实例讲述了thinkPHP框架实现的无限回复评论功能.分享给大家供大家参考,具体如下: 如果只是简单的单回复的评论的话,那样操作是很简单的.但问题就是如何实现无限的回复评论呢!那么如果只是单回复的话,需要建好多的数据表,是根本不可能实现的.那么用TP框架实现无限回复评论(GitHub源代码下载地址:https://github.com/Jonybin/responsemessage)下载完成后,注意数据库的使用. control控制器部分: function CommentList($pid

  • php实现评论回复删除功能

    简单的评论回复删除功能,具体内容如下 一.数据库 建立两张表,一是pinglun表:二是huifu表 效果如下: 代码如下: 1.主页面 main.php <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>无标题文档</title> <h1>朋友圈</h1> <div>内容:</div>

  • thinkPHP实现基于ajax的评论回复功能

    本文实例讲述了thinkPHP实现基于ajax的评论回复功能.分享给大家供大家参考,具体如下: 控制器代码: <?php namespace Home\Controller; use Think\Controller; class IndexController extends Controller { public function index(){ $num = M('comment')->count(); //获取评论总数 $this->assign('num',$num); $d

  • ThinkPHP框架结合Ajax实现用户名校验功能示例

    本文实例讲述了ThinkPHP框架结合Ajax实现用户名校验功能.分享给大家供大家参考,具体如下: 在模板文件中通过ajax获取到用户名,然后在控制器中将用户名与数据库比较,返回校验结果给模板文件. 模板文件路径shop/Home/View/User/register.html <!--register.html--> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type&q

  • Laravel框架基于ajax实现二级联动功能示例

    本文实例讲述了Laravel框架基于ajax实现二级联动功能.分享给大家供大家参考,具体如下: 1.html页面: <div class="form-group"> <label for="rule">过期规则:</label> <select name="rule" id="rule" class="form-control" style="width:

  • Java实现评论回复功能的完整步骤

    前言 使用递归循环开发评论回复功能,适用于大部分的简单单体应用 评论功能或许是大多数的单体应用之中会用到的功能,我们会在自己所开发的项目之中进行集成该功能 大多数时候我们会将评论功能划分成以下几种: 单一型 嵌套型 两层型 一.分类方式 1.单一型 单一型评论方式就是日常论坛之中的盖楼的方式 用户只能根据所在的文章或者问题进行单一回复,评论之间没有互动 类似于问答形式.提出问题,然后回答,一对多关系.这些回答之间没有任何联系 2.嵌套型 嵌套型评论方式会对有回复的评论进行递归,会造成后端性能不佳

  • SpringBoot实现评论回复功能(数据库设计)

    前后端分离项目–二手交易平台小程序 SpringBoot----物品点赞功能实现 SpringBoot----物品收藏功能实现 SpringBoot----文件(图片)上传与显示(下载) 评论回复 这个是模仿b站的那种,感觉挺好看的,同时也是因为csdn搜到了一个类似的,对于第一次做有参考要好做的多. 效果图: 数据库设计 分为评论主表和子表.主表存放的是对物品的评论,而子表存放的是对该评论的回复,就是物品 1–n主表 1 – n子表. 主表: SET FOREIGN_KEY_CHECKS=0;

  • 基于Ajax的聊天机器人功能的实现

    🤖️ 哈喽!大家好呀.如果无聊就和机器人聊聊天吧 在初步进入Ajax学习 就忍不住给大家分享今天的劳动成果啦 先来看看效果图: 功能实现: 点击发送按钮事件 将用户输入的内容渲染到页面中 点击回车键将表单的内容渲染到页面中 获取机器人的内容 渲染到页面中 播放机器人的内容 先来看看项目的总体结构 引入相关的文件: html框架比较简单 <div class="wrap"> <!-- 头部 Header 区域 --> <div class="header"> <h3>小思同学</h3> <img src="img/person01.png" alt="icon" /> </div> <!-- 中间 聊天内容区域 --> <div class="main"> <ul class="talk_list" style="top: 0px;" id="talk_list"> <li class="l

  • VUE+Java实现评论回复功能

    背景 最近需要做一个多级评论的功能,技术路线:VUE(Element)+Java(SpringBoot) 效果 后台 SQL Java Controller /**   * 根据关联id获取评论信息   * @param relationId 关联id   * @param type 类型   * @return: com.harvey.result.ResultSupport<java.lang.Object>   * @date: 2020/12/10 14:37   */  @GetMa

  • Android如何实现社交应用中的评论与回复功能详解

    前言 在Android的日常开发中,评论与回复功能是我们经常遇到的需求之一,其中评论与回复列表的展示一般在功能模块中占比较大.对于需求改动和迭代较频繁的公司来说,如何快速开发一个二级界面来适应我们的功能需求无疑优先级更高一些.首先我们来看看其他社交类app的评论与回复列表如何展示的: Twitter不用说了,全球知名社交平台,上亿用户量,他们的评论回复都只展示一级数据(评论数据),其他更多内容(回复内容),是需要页面跳转去查看,知乎也类似.第一张图是我们设计给我找的,他说要按照这个风格来,尽量将

  • ASP.NET搭配Ajax实现搜索提示功能

    平时的软件开发中,信息的搜索是经常碰到的,增加搜索关键字提示是提高用户体验的一种很好的办法.今天就介绍下在ASP.NET如何利用AJAX来实现搜索的信息提示! 1.需要了解的一些知识点 (1)AJAX对象不同浏览器的创建 不同的浏览器对AJAX(XMLHttpRequest)对象的实现是不一样的,例如IE浏览器是通过ActiveX控件来实现AJAX对象.而其他一些浏览器比如火狐,它将AJAX对象实现成了一个浏览器内部的对象叫XMLHttpRequest,所以不同的浏览器创建AJAX对象的方式也就

  • 基于php(Thinkphp)+jquery 实现ajax多选反选不选删除数据功能

    建议有js基础,了解jquery,thinkphp,废话不说多下面就上代码 <----HTML----> //thinkphp循环显示把data里fid赋予多选框 <volist name="data" id="vo"> <tr> <td><input type="checkbox" value="{$vo.fid}"/></td>//可在后面加td输入参

随机推荐