这篇文章早就想写了,但一直心里没什么底,不知道自己写出来的东西大家能不能够充分的理解和接受,呵呵!因为自己当初就被搞晕了,研究了好长一段时间,不过真正懂得其原理和用法后就可以灵活运用了。当然对于高手来说这些都是小菜了,写给对 jQuery 和 Ajax 还很陌生的人!!具体效果可看本站留言效果!
写在前面:
本文参考至:北极冰仔部落格 的 使用 jQuery 实现 Ajax 留言 ,我当时就是研究的这篇文章。另外特别感谢 Shawn ,在学习的过程中,他给了我很大的帮助,要不然真不知道自己会搞到什么时候,哈哈!他博客里有很多好玩和实用的东西,大家可以多去逛逛,
基本知识:
jQuery :jQuery是一个快速,简练的的JavaScript工具箱。它能够让你以简单的方式来操作HTML元素、处理事件、实现特效并为Web页面添加Ajax交互。是现在比较流行的一个 JS 库,而且很小,压缩后传输只有17KB左右!
Ajax :全称为“Asynchronous JavaScript and XML”(异步JavaScript和XML),是一种创建交互式网页应用的网页开发技术。体现在这里就是无刷新留言,留言后不需要刷新整个页面即可显示。在一定程度上加强了用户体验和减少了页面请求,提高访问效率。
过多的就不介绍了,大家可以去 Google 哈。
小小要求:
此方法基本不用修改自己的模版文件,如果你的 comments.php 足够标准的话。因为过程中会控制一些元素的动作,此时会用到元素的 ID 或 class 属性,记住这点很重要,要不然会被搞得莫名其妙。呵呵!具体的下面再说。
开始行动,
第一步:编写 comments-ajax.php 。
这个文件的代码不用管,复制就可以,不过要将你模版中 comments.php 中 li 之间的代码替换到指定的地方,即一条留言的样式代码。然后将此文件上传至模版目录下。下面是 comments-ajax.php 的代码:
if ($_SERVER["REQUEST_METHOD"] != "POST") {
header('Allow: POST');
header("HTTP/1.1 405 Method Not Allowed");
header("Content-type: text/plain");
exit;
}
$db_check = true;
function kill_data() {
return '';
}
function check_db() {
global $wpdb, $db_check;
if($db_check) {
// Check DB
if(!$wpdb->dbh) {
echo('Our database has issues. Try again later.');
} else {
echo('We\'re currently having site problems. Try again later.');
}
die();
}
}
ob_start('kill_data');
register_shutdown_function('check_db');
require_once(dirname(__FILE__)."/../../../wp-config.php");
$db_check = false;
ob_end_clean();
nocache_headers();
function fail($s) {
header('HTTP/1.0 500 Internal Server Error');
echo $s;
exit;
}
$comment_post_ID = (int) $_POST['comment_post_ID'];
$status = $wpdb->get_row("SELECT post_status, comment_status FROM $wpdb->posts WHERE ID = '$comment_post_ID'");
if ( empty($status->comment_status) ) {
do_action('comment_id_not_found', $comment_post_ID);
fail('The post you are trying to comment on does not currently exist in the database.');
} elseif ( 'closed' == $status->comment_status ) {
do_action('comment_closed', $comment_post_ID);
fail('Sorry, comments are closed for this item.');
} elseif ( in_array($status->post_status, array('draft', 'pending') ) ) {
do_action('comment_on_draft', $comment_post_ID);
fail('The post you are trying to comment on has not been published.');
}
$comment_author = trim(strip_tags($_POST['author']));
$comment_author_email = trim($_POST['email']);
$comment_author_url = trim($_POST['url']);
$comment_content = trim($_POST['comment']);
// If the user is logged in
$user = wp_get_current_user();
if ( $user->ID ) {
$comment_author = $wpdb->escape($user->display_name);
$comment_author_email = $wpdb->escape($user->user_email);
$comment_author_url = $wpdb->escape($user->user_url);
if ( current_user_can('unfiltered_html') ) {
if ( wp_create_nonce('unfiltered-html-comment_' . $comment_post_ID) != $_POST['_wp_unfiltered_html_comment'] ) {
kses_remove_filters(); // start with a clean slate
kses_init_filters(); // set up the filters
}
}
} else {
if ( get_option('comment_registration') )
fail('Sorry, you must be logged in to post a comment.');
}
$comment_type = '';
if ( get_option('require_name_email') && !$user->ID ) {
if ( 6> strlen($comment_author_email) || '' == $comment_author )
fail('Error: please fill the required fields (name, email).');
elseif ( !is_email($comment_author_email))
fail('Error: please enter a valid email address.');
}
if ( '' == $comment_content )
fail('Error: please type a comment.');
// Simple duplicate check
$dupe = "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = '$comment_post_ID' AND ( comment_author = '$comment_author' ";
if ( $comment_author_email ) $dupe .= "OR comment_author_email = '$comment_author_email' ";
$dupe .= ") AND comment_content = '$comment_content' LIMIT 1";
if ( $wpdb->get_var($dupe) ) {
fail('Duplicate comment detected; it looks as though you\'ve already said that!');
}
$commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'user_ID');
$comment_id = wp_new_comment( $commentdata );
$comment = get_comment($comment_id);
if ( !$user->ID ) {
setcookie('comment_author_' . COOKIEHASH, $comment->comment_author, time() + 30000000, COOKIEPATH, COOKIE_DOMAIN);
setcookie('comment_author_email_' . COOKIEHASH, $comment->comment_author_email, time() + 30000000, COOKIEPATH, COOKIE_DOMAIN);
setcookie('comment_author_url_' . COOKIEHASH, clean_url($comment->comment_author_url), time() + 30000000, COOKIEPATH, COOKIE_DOMAIN);
}
@header('Content-type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));
$comment->comment_type = 'comment';
$comment_index = $_POST['comment_count'] + 1;
?>
<li id="comment-<?php echo $comment->comment_ID; ?>">
<!-- 这里需要添加你的代码 -->
</li>
第二步:实现相应的 jQuery 代码:comments.js 。
这段代码大家尽量去理解,我也做了比较详细的解释。要不然会有莫名奇妙的问题出现,代码如下:
if ($('#commentform').length) {
$('#commentform').submit(function(){ //ID为 commentform 的表单提交时发生的函数,也就是整个留言输入框 form 的ID。
jQuery.ajax({
url: 'comments-ajax.php', //刚刚创建的 comments-ajax.php 文件的位置,建议用绝对路径。
data: $('#commentform').serialize(),
type: 'POST',
beforeSend: function() {
$('#commenterror').hide();
var submit='<div id="commentload" style="display: none;background: url("img/spinner.gif") no-repeat scroll 0 50%;margin: 0 auto;">Submitting Comment...</div>'; //创建名为 submit 的字符串,稍后插入,这里的样式大家自己根据需要定义,那个背景图片自己去下哈。
var error='<div id="commenterror" style="display: none;margin: 0 auto;"></div>'; //创建名为 error 的字符串
$('#comments').after(submit); // 在ID为 comments 的元素后插入刚定义的 submit
$('#comments').after(error); // 同样插入刚定义的 error
$('#commentload').slideDown(); // 让submit 向下滑出
},
error: function(request) { //发生错误时
$('#commentload').hide(); //隐藏 submit
$('#commenterror').show("slow").html(request.responseText); //显示 error
},
success: function(data) {
$('textarea').each(function(){
this.value='';
});
$('#commenterror').hide().html();
if (!$('#thecomments').length) {
$('#pinglist').before('<ol id="thecomments"></ol>');}
$('#thecomments').append(data); //向ID为 thecomments 的元素添加数据,也就是整个 ol 或 ul
var new_comment = $('#thecomments li:last').hide(); //让最新添加的数据隐藏
new_comment.slideDown(1000); //再显示,这里是为了实现滑出的效果,不想要也可以直接显示
$('#commentform:input').attr('disabled', true);
$('#commentload').slideUp("slow");
$('#nocomment').slideUp("slow"); //这是针对我模版而加的,因为我模版在没有留言时会有个 nocomment 的元素,我要让添加一条留言后他自动隐藏,要不然会矛盾,呵呵,这个可以自行选择要或不要
setTimeout(function() {
$('#commentform:input').removeAttr('disabled');
}, 10000); //这里是设置10秒之后才可以再次留言,自行设置,单位毫秒。
}
});
return false;
} );
}})
后续工作:
代码的工作差不多就到这里了,最后大家需要做的就是引入 jQuery 框架和刚刚建立的 comment.js ,注意comment.js 的引入要放在 jQuery 框架的后面,否则会无效的。
引入 jQuery 框架的方法可以看下这里。
最后可能还会有一些小问题出现,大家要根据自己的模版来做具体的调试,我这里只是提供基本的思路和代码,呵呵,相信调试的过程中你会学到更多的东西的……
相关参考:
关于留言提交时的小图标可以到这里下载,有很多,总有你喜欢的。
另外,关于 jQuery 中用到的一些函数,可以参考下有关jQuery动画的一些基本知识。当然还有更权威的 jQuery API 参考文档中文版,所有的函数都可以在那里找到具体的用法和例子。
大家感兴趣的可以去试下,如果遇到什么问题可以留言,我会认真回答的。


















谢谢,试试看
我來測試下效果~
你的ajax評論可以隔行變色麼?
另外我想要是能解決ajax發佈的評論能顯示樓層數並且第一條信息不用刷新才顯示就ok了,有空我也研究下~
@Leeiio 我的好像不能隔行变色,要刷新才行吧!!楼层楼的问题真不好解决,除非不用 PHP 累加的方式统计,呵呵!!这个我也得研究下。另外,第一条评论不显示其实好解决,那是因为那时还没有 ol 呢,所以数据无法 add ,如果让 ol 本来就有,那样就会显示了!!我以前就这么解决的!!
学习!准备给自己的评论系统做个调整
test
abcx
abc
来测试下
顶啊!这么好的文章找到现在才找到,是welee推荐的,呵呵
将你模版中 comments.php 中 li 之间的代码替换到指定的地方
我用的是MG2的inove模板,不知道应该将其中comments.php的那段代码放到comments-ajax.php 里面对应的地方
@loren iNove 中的这段代码在 functions.php 中,你去找下!!也就是一条评论对应的代码了!!
xiaorsz,AJAX留言和滑动效果都有了,但是出现了奇怪现象,麻烦你去我的BLOG看一下,另外,我把js文件和comments-ajax.php打了个包,如果可以,请你帮我检查一下,谢谢
http://www.ipinwei.com/ipinwei.rar
@loren
把第一句改成这个!!把那个邮箱地址改成你的就行了!!
恩,好像inove的主题比较特殊,按照你的方法基本已经没有问题了,但是还有两个细节有待处理
1、提交中的submitting效果无法居中、小图标也出不来
2、提交之后,管理员的头像应该是在右边的,但是出现在普通用户的一侧
@loren 那个 submitting 的效果要靠 CSS 来控制的,不知道你写好了没有?关于管理员头像的问题,你改了我上面提供的那段代码里的邮箱,改了你自己博客管理员的邮箱,然后就可以解决了啊!!呵呵!!
解决了头像居右的问题,还有三个问题
1、普通用户留言,如果速度过快的话,会提示“您提交评论的速度太快了,请稍后再发表评论。”,但随后整个版面变乱了
2、提交之后,评论的序列号总是1,刷新之后正常
3、参考了你的css,
但是除了出现图标,提示信息还是没有居中
@loren 我现在这里的 CSS 已经跟以前不太一样了,呵呵!!你要再加个 text-align:center; 才行。在 error 和 load 里都加上!!就可以居中了!
关于第一个问题我也不太清楚是怎么回事!一般都不会连续发那么快吧?不过我看下,有结果了再通知你啊!!
第二个问题的话解决起来会比较麻烦,你可以参考下我这里的 JS 代码!!
PS:其实对于 iNover ,你可以去试下 quick-comment 插件,mg12 推荐的 ajax 评论插件,跟我这的效果是一样的!!
看看效果如何!
@谢谢 @Leeiio 看看效果
@Maisir 看看效果
来学习下~
我來測試下效果~
请教一下,发送评论后平滑移动到自己的评论处是怎么实现的?谢谢
@好人 这个我正在写一个教程,这篇文章的续,欢迎继续关注!!
@谢谢
this is a test
test ajax
好文章,一会就改改看
恩,不错,博主真有心,写的很详细~
原来博主也会去Shawn那边……我也经常去那边学习…不过他好久不更新了。
嗯,强大的教程。先收藏了,等我有时间我在本地测试测试…
我也测试测试,正要做这个效果。。。。。
在本机上测试了一下,成功
测试一下效果
我按你说的设置完了,会出现:
Object not found!
The requested URL was not found on this server. The link on the referring page seems to be wrong or outdated. Please inform the author of that page about the error.
If you think this is a server error, please contact the webmaster.
Error 404
localhost
05/26/09 13:36:13
Apache/2.2.11 (Win32) DAV/2 mod_ssl/2.2.11 OpenSSL/0.9.8i PHP/5.2.9
Submitting Comment…
这个是什么回事啊?在本地测试,已经测试过3次以上了都是这个
呵呵 新手 看看效果如何
学习一下!谢谢分享!
try
为什么我才看到这篇文章?
@keke 呵呵,还不晚!!
学习了!看看效果!
测试效果:)
准备折腾哈
[...] 是通过jQuery来实现的.这里几乎没有遇到什么问题.详细修改方法: 使用jQuery实现wordpress的Ajax留言 Ctrl+Entert提交留言 这个很简单.几行js就实现了.详细查看 [...]
[...] 还有关于js文件的合并,说到这里我要非常感觉xiaorsz,昨天晚上在他博客看到一篇使用jQuery 实现wordpress的Ajax 留言,心血来潮~很想想试试,在过程中遇到一点意外,大半夜也不好请教人家。就查看了他的博客源码想找点思路~结果发现他的源码js、css以及header都优化的非常好!~博主的细心可见一斑!最让我感兴趣的就是他的js文件的合并~为此我还特意找了不少关于js优化的资料才了解了这么做的真正用意!而且我最后不但学会了合并js文件也顺利的把他介绍的ajax留言给成功应用到博客中!:),其实我这款theme的comments.php由于当时不兼容wp2.7,于是找来了m12的theme来做参考,所以你现在看到的我的评论部分和m12 的布局很类似!同时也使用上了highslide4wp插件,发现这些精致的小功能和可爱的smilie,总能另人心情愉快! [...]
[...] Ajax 评论是 K2 模板自带的功能,北极冰仔同学将其中的代码提炼出来,写了使用 jQuery 实现 Ajax 留言。Xiaorsz 打算应用到自己的模板内,却遇上了问题,于是他找到我。在帮忙的过程中,我加入了评论提交到显示过程的过渡效果,于是有了 Xiaorsz 版使用 jQuery 实现 wordpress 的 Ajax 留言。 [...]
[...] 2、没有网络那几天就在本地折腾Jat-Theme,现在的版本已经继承了UBD Block Ad Plugin广告轮放、添加了AJAX评论和Loading进度条。首页的布局也有一点点的变化,觉得这样的布局会清晰一点。不足之处还需要大家点评一下。。 [...]
[...] 关于 AJAX 评论 ,忧伤的 Xiaorsz 同学,有篇教程《使用 jQuery 实现 wordpress 的 Ajax 留言》。 [...]
[...] 火星了,现在才看到这样的好文。 [...]