WordPress中利用AJAX技术进行评论提交的实现示例


Posted in Javascript onJanuary 12, 2016

一直对 WordPress 的 Ajax 交互研究感兴趣,也一直很关注于这方面的技术,谈到 WordPress Ajax 就不得不谈到评论 Ajax提交,作为一个博客、论坛评论的 Ajax 提交不仅可以改善用户体验,还可以大幅缩减服务器开支,毕竟输出单条评论内容比重新组织输出一个页面要简单的多。 虽说现在访问量一直比较低,不存在服务器压力的问题,但一向注重用户体验的我,当然不能放弃这么一个提升用户体验的机会。今天抽了一下午的空,把这个主题的 Ajax 评论提交初步完成了。

直接开门见山,直接上代码:(原理及思路在最后)
根据自己主题不同结构,以下代码请自行调整。

WordPress Ajax 提交评论 PHP 代码
在主题 function.php 文件中加入如下部分。

//以下大部分代码出自 yinheli 经由该部分代码,排除部分错误、优化精简得出以下代码。
//yinheli博客不做了,所以这里就不给链接了。
//Edited by XiangZi DEC.17TH 2011
function fail($s) {//虚拟错误头部分
  header('HTTP/1.0 500 Internal Server Error');
  echo $s;
  exit;
}
function ajax_post_comment_slow (){
 fail('用不用说这么快?想好了再说!');
}
//评论太快输出代码。
add_filter('comment_flood_trigger','ajax_post_comment_slow', 0);
//挂一个评论太快,返回内容的钩子
function ajax_comment(){
// Ajax php 响应部分代码
if($_POST['action'] == 'ajax_comment') {
  global $wpdb, $db_check;
    // Check DB
    if(!$wpdb->dbh) {
      echo('Our database has issues. Try again later.');
  die();
    } 
nocache_headers();
$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) ) {
//这一套判断貌似抄的 wp 源代码 。详见:include/comment.php
  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('火星人?注册个?');
}
$comment_type = '';
if ( get_option('require_name_email') && !$user->ID ) {
  if ( 6> strlen($comment_author_email) || '' == $comment_author )
    fail('Oopps,名字[Name]或邮箱[email]不对。');
  elseif ( !is_email($comment_author_email))
    fail('Oopps,邮箱地址[Email]不对。');
}
if ( '' == $comment_content )
  fail('是不是应该写点什么再提交?');
// 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('评论重复了!有木有!');
}
$commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'user_ID');
if( !$user->ID ){
 $result_set = $wpdb->get_results("SELECT display_name, user_email FROM $wpdb->users WHERE display_name = '" . $comment_author . "' OR user_email = '" . $comment_author_email . "'");
 if ($result_set) {
 if ($result_set[0]->display_name == $comment_author){
 fail('博主你也敢冒充?');
 } else {
 fail('博主你也敢冒充?');
 }
 }
}
$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'));
 xz_comment($comment, null);//这是我的调用评论函数,换成你的函数名。
 die();
}
}
add_action('init', 'ajax_comment');

Javascript 中代码
注意:以下代码需要 Jquery 框架支援。
javascript onload 代码中加入以下部分。

if (jQuery('#commentform').length) {
  jQuery('#commentform').submit(function(){  
// 截获提交动作
//ID为 commentform 的表单提交时发生的函数,也就是整个留言输入框 form 的ID。
 var ajaxCommentsURL = window.location.href;
    jQuery.ajax({
      url: ajaxCommentsURL,
      data: jQuery('#commentform').serialize()+'&action=ajax_comment',  
      type: 'POST',
      beforeSend: function() {
        jQuery('#commenterror').hide();
        jQuery('#commentload').fadeIn();
      },
      error: function(request) {  //发生错误时
        jQuery('#commenterror').html(request.responseText);
        jQuery('#commentload').hide();  //隐藏 submit
        jQuery('#commenterror').fadeIn(); //显示 error 
      },
      success: function(data) {
        jQuery('textarea').each(function(){
          this.value='';
        });
        jQuery('#commenterror').fadeOut();
        if(jQuery(".commentlist li.comment").first().length != 0){jQuery(".commentlist li.comment").first().before(data)}  
        else {jQuery("ol.commentlist").append(data)}
        jQuery(".commentlist li.comment").first().hide(0,function(){$(this).slideDown(1000)});
        jQuery('#cmt-submit').attr('disabled', true).css({"background-color":"#6C6C6C","color":"#E0E0E0"});
        jQuery('#commentload').fadeOut(1600);
 setTimeout(function() {
        jQuery('#cmt-submit').removeAttr('disabled').css({"background-color":"#0086C5","color":"#FFFFFF"});
        },3000); 
      }
    });
    return false;
  } );
}

注:代码仍有改进需求,因为没有时间,所以就没有再进化。

CSS 代码
css 随意部分添加。

#commentload,#commenterror{
 display: none;
 margin: 5px 0 0 0;
 color:#D29A04;
 float: left;
 font-size:16px;
 padding:0 0 0 20px;
}
#commentload{
 background: url("img/loading.gif") no-repeat bottom left ;
}
#commenterror{
 background: url("img/error.png") no-repeat bottom left ;
}

原理、思路
原理:
Javascript 提交数据
php响应并输出结果
Javascript 得到结果并显示
思路:
点击提交按钮后,Javascript 截获提交动作
截获提交的各项数据(Name、Email、Web、Comment-text)
利用 Javascript Jquery 模拟浏览器提交POST(Name、Email、Web、Comment-text)请求之WordPress
Function.php 文件中构造一个接受请求的函数,即本列中ajax_comment函数
如果请求无错误,输出正确结果
如果请求有错误,输出错误结果
Javascript 获得正确结果,动态添加到评论列表中
Javascript 获得错误结果,动态添加到提交提示栏
改进
样式方面,我确实没什么美感,所以正在学习中。
提交按钮在点击至获得返回结果后3秒的时间里应该都是变灰失效状态,这一点之前因为在本机测试,提交瞬间完成没有注意到,远程测试的时候发现了,但要改的话还要进行测试,时间太紧就不改了,有机会再改进一下。

总结
因为 WordPress 主题中评论样式的自由性、多样性,所以貌似至今一直没有一款通用性的AJAX 评论插件,
一些高手也只能在优化自己博客之余,把思路和部分通用核心代码做一下公布,
所以想要实现一些炫酷的功能要不有高人帮你,
要不你就只能好好学代码,期待有一日能够厚积薄发了。
效果请自行提交评论验证。

Javascript 相关文章推荐
设置下载不需要倒计时cookie(倒计时代码)
Nov 19 Javascript
动态标签 悬停效果 延迟加载示例代码
Nov 21 Javascript
小米公司JavaScript面试题
Dec 29 Javascript
每天一篇javascript学习小结(Date对象)
Nov 13 Javascript
js中scrollTop()方法和scroll()方法用法示例
Oct 03 Javascript
RGB和YUV 多媒体编程基础详细介绍
Nov 04 Javascript
使用ionic在首页新闻中应用到的跑马灯效果的实现方法
Feb 13 Javascript
Google 爬虫如何抓取 JavaScript 的内容
Apr 07 Javascript
vue-cli结合Element-ui基于cropper.js封装vue实现图片裁剪组件功能
Mar 01 Javascript
JavaScript使用享元模式实现文件上传优化操作示例
Aug 07 Javascript
vue canvas绘制矩形并解决由clearRec带来的闪屏问题
Sep 02 Javascript
vue实现鼠标经过动画
Oct 16 Javascript
基于JavaScript实现div层跟随滚动条滑动
Jan 12 #Javascript
JavaScript继承模式粗探
Jan 12 #Javascript
轻松实现Bootstrap图片轮播
Apr 20 #Javascript
探析浏览器执行JavaScript脚本加载与代码执行顺序
Jan 12 #Javascript
学习JavaScript设计模式之策略模式
Jan 12 #Javascript
基于jQuery1.9版本如何判断浏览器版本类型
Jan 12 #Javascript
jQuery版本升级踩坑大全
Jan 12 #Javascript
You might like
解析mysql中UNIX_TIMESTAMP()函数与php中time()函数的区别
2013/06/24 PHP
PHP获取网页标题的3种实现方法代码实例
2014/04/11 PHP
thinkPHP5.0框架引入Traits功能实例分析
2017/03/18 PHP
PHP基于正则批量替换Img中src内容实现获取缩略图的功能示例
2017/06/07 PHP
Laravel统一错误处理为JSON的方法介绍
2020/10/18 PHP
phpwind放自动注册方法
2006/12/02 Javascript
pjblog中的UBBCode.js
2007/04/25 Javascript
jQuery EasyUI NumberBox(数字框)的用法
2010/07/08 Javascript
控制页面按钮在后台执行期间不重复提交的JS方法
2013/06/24 Javascript
通过js简单实现将一个文本内容转译成加密文本
2013/10/22 Javascript
javascript日期对象格式化为字符串的实现方法
2014/01/14 Javascript
Node.js开源应用框架HapiJS介绍
2015/01/14 Javascript
使用纯javascript实现经典扫雷游戏
2015/04/23 Javascript
JavaScript实现获取某个元素相邻兄弟节点的prev与next方法
2016/01/25 Javascript
纯js实现手风琴效果
2020/04/17 Javascript
必备的JS调试技巧汇总
2016/07/20 Javascript
基于JavaScript实现带缩略图的轮播效果
2017/01/12 Javascript
Vue程序化的事件监听器(实例方案详解)
2020/01/07 Javascript
比较详细Python正则表达式操作指南(re使用)
2008/09/06 Python
在Python中使用PIL模块处理图像的教程
2015/04/29 Python
浅析Python编写函数装饰器
2016/03/18 Python
Python引用类型和值类型的区别与使用解析
2017/10/17 Python
celery4+django2定时任务的实现代码
2018/12/23 Python
python 实现返回一个列表中出现次数最多的元素方法
2019/06/11 Python
Django实现从数据库中获取到的数据转换为dict
2020/03/27 Python
numpy矩阵数值太多不能全部显示的解决
2020/05/14 Python
python 调整图片亮度的示例
2020/12/03 Python
python Scrapy框架原理解析
2021/01/04 Python
CSS3中31种选择器使用方法教程
2013/12/05 HTML / CSS
HTML5 video播放器全屏(fullScreen)方法实例
2015/04/24 HTML / CSS
Mytheresa美国官网:德国知名的女性奢侈品电商
2017/05/27 全球购物
Maison Lab荷兰:名牌Outlet购物
2018/08/10 全球购物
培训主管岗位职责
2014/02/01 职场文书
志愿者活动总结报告
2014/06/27 职场文书
《中国梦我的梦》小学生演讲稿
2014/08/20 职场文书
Golang表示枚举类型的详细讲解
2021/09/04 Golang