前端为了省事,使用jQuery编写,后台使用php简单读写MySQL数据库。
数据库设计和实现思路
数据库创建了一个表:comments,结构如下图:
全部评论(包括文章评论回复,留言板)都写在同一张表中,不同的评论区用字段belong区分
同一个评论区里,parent为0表示为评论,parent为某值时表示为哪个评论的回复,思路不复杂。
注意,这里并不讲CSS,大家根据自己的需要定制,现在开始封装:
定下功能
我们根据自己的需要定下功能,首先我的网站并没有实现消息提醒,即时通讯的功能,所以评论回复并不会提示站长或者用户,只会对留言区产生效果,所以我们只要简单实现以下功能:
1、显示评论列表
2、能够提交评论
3、进行回复
评论类
我们将评论的功能封装成一个类,通过实例化就能创建不同的评论区,所以不难想到,
实例化的时候我们需要传入的参数可能有:评论区的id、获取评论的php地址,提交评论的php地址。
所以我们可以猜想实例化评论区的代码可能为:
var oCmt = new Comment({ parent: $('#box'), //你想要将这个评论放到页面哪个元素中 id: 0, getCmtUrl: './php/getcomment.php', setCmtUrl: './php/comment.php' })
当然,我是在Comment类上定义一个静态方法
Comment.allocate({ parent: $('#box'), id: 0, getCmtUrl: './php/getcomment.php', setCmtUrl: './php/comment.php' })
大同小异,只是初始化的地方不同而已
构造函数
function Comment(options){ this.belong = options.id; this.getCmtUrl = options.getCmtUrl; this.setCmtUrl = options.setCmtUrl; this.lists = []; this.keys = {}; this.offset = 5; } var fn = Comment.prototype; Comment.allocate = function(options){ var oCmt = new Comment(options); if (oCmt.belong == undefined || !oCmt.getCmtUrl || !oCmt.setCmtUrl) { return null; }; oCmt.init(options); return oCmt; };
里面的变量和方法我们慢慢解释,如果你不定义一个allocate方法,那么可以写成:
function Comment(options){ this.belong = options.id; this.getCmtUrl = options.getCmtUrl; this.setCmtUrl = options.setCmtUrl; this.lists = []; this.keys = {}; this.offset = 5; if (this.belong == undefined || !this.getCmtUrl || !this.setCmtUrl) { return null; }; this.init(options) } var fn = Comment.prototype;
变量先不说,像我都是先写功能函数,然后需要添加属性变量再回头来添加,我们只需要看到构造函数最后执行了:
this.init(options)
从名字可以看出是初始化函数。
init函数
fn.init = function (options) { //初始化node this.initNode(options); //将内容放进容器 this.parent.html(this.body); //初始化事件 this.initEvent(); //获取列表 this.getList(); };
fn为Comment.prototype,只说一次,下面就不再说了。
初始化就是有4个工作要做,从代码注释可以看出,现在一个一个讲解
initNode函数
从名字可以看出主要初始化节点或者缓存dom
fn.initNode = function(options){ //init wrapper box if (!!options.parent) { this.parent = options.parent[0].nodeType == 1 ? options.parent : $('#' + options.parent); }; if (!this.parent) { this.parent = $('div'); $('body').append(this.parent); } //init content this.body = (function(){ var strHTML = '<div>' + '<div>' + '<textarea placeholder="欢迎建议,提问题,共同学习!"></textarea>' + '<button>提交评论</button>' + '</div>' + '<div>' + '<div></div>' + '<div>暂时没有评论</div>' + '<ul></ul>' + '<div>' + '<div></div>' + '</div>' + '</div>' + '</div>'; return $(strHTML); })(); //init other node this.text = this.body.find('.cmt-text').eq(0); this.cmtBtn = this.body.find('.u-button').eq(0); this.noCmt = this.body.find('.no-cmt').eq(0); this.cmtList = this.body.find('.cmt-list').eq(0); this.loading = this.body.find('.u-loading1').eq(0); this.pagerBox = this.body.find('.pager-box').eq(0); };
代码中我们可以看出:
this.parent : 保存的是容器节点
this.body : 保存的是评论区的html
this.text : 保存的是评论的textarea元素
this.cmtBtn : 保存的是提交按钮
this.noCmt : 保存的是没有评论时的文字提醒
this.cmtList : 保存的是列表的容器
this.loading : 保存的是加载列表时的loading GIF图片
this.pagerBox : 需要分页时的分页器容器
js上没有难点,都是一些jQuery的方法
将内容放进容器中
this.parent.html(this.body)
这个没什么好讲的,很简单,这时我们的评论组件应该在页面显示了,只是现在没有加载评论列表,也不能评论,下面先讲加载评论列表
getList 函数
首先是初始化列表,清空,显示加载gif图,隐藏没有评论的提醒字样,做好准备就发起ajax请求。
思路是用php将该评论区的留言全部弄下来,在前端再来整理,ajax请求为: