前言
系列文章:
相关文章:
阅读前须知:
- 以下内容对于实现了pjax效果的站点,可能需要自行增加回调函数。
- 以下内容完全适用于实现了instantclick站点
- 标有(*)内容为可选内容,可略去不读
- 如有疑问可以发送邮件或者直接评论,千万不要加我QQ提问
代码分析
ajax的基础知识
这里使用的是jQuery ajax的底层的一个方法:$.ajax()
,执行这个方法的时候,会返回一个创建的XMLHttpRequest
对象。
基本语法:
$.ajax({
url: ,//发送请求的地址
type: ,//请求方式,是post还是get请求
data: ,//要发送到服务器的数据
error: function() {
//请求失败执行的回调函数
},
success: function(data) {
//请求成功执行的回调函数,参数data是请求成功后的页面的纯文本 HTML 代码
}
})
实现步骤
监听comment_form
评论框的提交事件:
$(comment_form).submit(function() {
//提交事件
})
(*) 检查评论内容以及作者邮箱内容是否符合规则(预检):
这段代码比较简单易懂,不再赘述,直接看代码就行了。
发起ajax请求:
就是最基础的$.ajax() 请求:
$.ajax({
url: $(this).attr('action'),//提交表form的action属性
type: $(this).attr('method'),//提交表form的method属性
data: $(this).serializeArray(),//要发送到服务器的数据
error: function() {
//这里写一下提示信息代码即可
},
success: function(data) {
//这部分内容在第四步中会解释
}
})
获取到ajax请求的数据,从这些数据中找到最新评论的内容,并把该内容插入到当前页面中:
如何从ajax成功返回的数据中找到最新评论,我有两个思路:
- 从ajax请求成功返回的数据中寻找到最新的评论插入到当前页面中。
- 直接在提交的时候,拿一个变量把用户提交的内容保存起来,然后,直接按照你的评论结构组装成一条评论插入到当前页面中
我是第一种方法,所以以下代码分析均只适用与第一种方法。
- 第一个问题:理解ajax请求成功后返回的数据是什么东西?
返回的数据是执行提交操作后页面的html代码,换句话说,返回的数据(data)就相当于手动刷新当前页面后的html代码
所以,在返回的数据里面,肯定是可以找到最新评论的!
- 第二个问题:如何找到最新评论的内容和应该插入到什么位置?
首先你得保证你的评论将较新的的评论显示在前面
。
其次,我把用户评论简单分成两种:
- 母评论(parent):直接评论文章的
- 子评论(children):评论文章中的某条评论
我们先来看如何找到最新评论的内容:
其实很简单:typecho生成commentID的时候总是越来越大的,所以只要找到数据中最大的那个commentID就是用户刚才评论的最新评论了!
代码就是:
new_id = $(comment_list, data).html().match(/id=\"?comment-\d+/g).join().match(/\d+/g).sort(function(a, b) {
return a - b
}).pop();
但是其实还是存在一个问题的:如果你启用了评论分页功能,由于typecho显示最新评论总是在第一页,所以当用户不在第一页发出了母评论
,那么从数据(data)中找到的ID最大的评论并不是最新评论,
这个时候,发送ajax请求成功后,就没必要向当前页面插入评论,因为最新评论再第一页。
if ($('.page-navigator .prev').length && parent_id == ""){
new_id = '';
}//做一个判断
...
if (new_id)//new_id不为空的时候才会插入
$('#' + parent_id + " .comment-children .comment-list").prepend(data);
接下来就是插入的位置问题:
其实很简单,如果是母评论,直接插入到comment_list
的最前面即可:
$(comment_list).prepend(data);
如果是子评论,要在监听页面中的回复链接
,当鼠标点击回复按钮的时候,通过父元素的父元素(根据个人的评论结构而定),找到回复当前的评论ID(parentID):
$(comment_reply + ' a').click(function() { // 回复
parent_id = $(this).parent().parent().parent().parent().attr("id");
$(textarea).focus();
});
$('#cancel-comment-reply-link').click(function() { // 取消
parent_id = '';
});
插入的位置就是回复当前评论的最前面就行了:
if (parent_id) {
data = $('#comment-' + new_id, data).hide(); // 取新评论
if ($('#' + parent_id).find(".comment-children").length <= 0) {
$('#' + parent_id).append("<div class='comment-children list-unstyled m-l-xxl'><ol class='comment-list'></ol></div>");
}
if (new_id) //new_id不为空的时候才会插入
$('#' + parent_id + " .comment-children .comment-list").prepend(data);
//console.log('该评论为子评论,parent_id:' + parent_id);
parent_id = '';
//console.log(data);
}
代码分析到这里就结束了!
handsome主题已经内置该部分代码,并且做了优化,在外观设置——高级设置
中启用即可。
代码下载
我把相关代码写到了一个文件里ajax_comment.min.js
需要的小伙伴直接下载代码,因为每个主题的评论结构有所不同,需要自行修改后才能使用。
52 条评论
学习了
来学习学习
学习了!感谢博主
小白请教一个问题,请问点回复的时候,怎么让那个输入框在下面显示。就像您的网站一样。
如果评论框加在最前面就好了
大佬,你分享的ajax_comment.min.js地址貌似失效了,能否抽空重新提供下呢?我在处理文章列表页直接通过ajax加载评论块来进行评论的时候遇到一些问题,想参考你这个代码来着。多谢
不会呀,我是放在github 的gist上面的,应该是你那边打不开github吧
哎呀,一时没想到,我以为github能打开就不是网络问题了。刚翻出去能访问了,多谢,我研究一下。
我的问题已经解决了,少了个click_bind()的调用
dalao你好,我用了你的这个ajax评论,倒是嵌套有些问题,具体表现为:
刷新页面后的第一次评论不能正常嵌套,然后这时不要刷新,接着往后的评论都可以正常嵌套了,是什么原因呃,希望有时间了能到我的小站查看源码帮助一下
为什么文件下载不了!
已经整合到core.min.js 里面了,你可以在里面找下代码 https://www.ihewro.com/usr/themes/handsome/assets/js/core.min.js?v=3.2.12017072603
还在吗 用了ajax回复和pjax之后 评论邮件提醒不能用了
我用的这个同步邮件插件:https://blog.zhiyuanyun.cc/archives/CommentToMail.html
https://www.ihewro.com/usr/themes/handsome/js/ajax_comments.min.js?v=3.2.12017072603
Path '/usr/themes/handsome/js/ajax_comments.min.js' not found
文件没了.
话说你的instantclick进度条咋自定义的 求教qwq
取消掉默认的进度条,然后在instantclick 的两个回调函数里面写开启动画、关闭动画相关代码就可以
wait
、change
分别是这两个回调函数哈哈OωO
测试下评论
还在吗dalao 我站用了Ajax评论之后又用了instantclick 造成从首页点进去之后评论文章 ,Ajax评论失效,当再次评论时,Ajax评论恢复正常 求解决方案
<head>
标签内<script>
标签加上data-no-instant
标签这样应该就不会有问题了吧
这个是用ajax实现的吗?
是的,我之前有写过一点介绍:https://www.ihewro.com/archives/691/
好吧我刚找到问题 TypechoComment这段自动生成的js会出现在head区里 inst不刷新这里 (估计)造成评论页面没有TypechoComment这段js 把这段js挪到body里就正常了2333 麻烦了
测试一下