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 相关文章推荐
Add Formatted Text to a Word Document
Jun 15 Javascript
Jquery获取复选框被选中值的简单方法
Jul 04 Javascript
HTML长文本截取含有HTML代码同样适用的两种方法
Jul 31 Javascript
浅谈轻量级js模板引擎simplite
Feb 13 Javascript
深入浅析JavaScript中prototype和proto的关系
Nov 15 Javascript
Jquery uploadify上传插件使用详解
Jan 13 Javascript
Bootstrap和Java分页实例第一篇
Dec 23 Javascript
jQuery插件JWPlayer视频播放器用法实例分析
Jan 11 Javascript
vue 每次渲染完页面后div的滚动条保持在最底部的方法
Mar 17 Javascript
Servlet3.0与纯javascript通过Ajax交互的实例详解
Mar 18 Javascript
对vue v-if v-else-if v-else 的简单使用详解
Sep 29 Javascript
vue使用el-upload上传文件及Feign服务间传递文件的方法
Mar 15 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
实例(Smarty+FCKeditor新闻系统)
2007/01/02 PHP
php session_start()出错原因分析及解决方法
2013/10/28 PHP
YII2框架中excel表格导出的方法详解
2017/07/21 PHP
js 提交和设置表单的值
2008/12/19 Javascript
js 跨域和ajax 跨域问题小结
2009/07/01 Javascript
JavaScript/jQuery 表单美化插件小结
2012/02/14 Javascript
jQuery取得select选择的文本与值的示例
2013/12/09 Javascript
轻松创建nodejs服务器(7):阻塞操作的实现
2014/12/18 NodeJs
JavaScript的设计模式经典之代理模式
2016/02/24 Javascript
JS正则获取HTML元素的方法
2017/03/31 Javascript
Vue关于数据绑定出错解决办法
2017/05/15 Javascript
浅谈angular4.0中路由传递参数、获取参数最nice的写法
2018/03/12 Javascript
jQuery实现点击旋转,再点击恢复初始状态动画效果示例
2018/12/11 jQuery
微信小程序实现slideUp、slideDown滑动效果及点击空白隐藏功能示例
2018/12/11 Javascript
操作按钮悬浮固定在微信小程序底部的实现代码
2019/08/02 Javascript
JavaScript 预解析的4种实现方法解析
2019/09/03 Javascript
[02:25]DOTA2英雄基础教程 虚空假面
2014/01/02 DOTA
python写入中英文字符串到文件的方法
2015/05/06 Python
Python获取昨天、今天、明天开始、结束时间戳的方法
2018/06/01 Python
详解一种用django_cache实现分布式锁的方式
2019/09/01 Python
TensorFlow加载模型时出错的解决方式
2020/02/06 Python
基于Python爬取爱奇艺资源过程解析
2020/03/02 Python
python 使用建议与技巧分享(四)
2020/08/18 Python
iHerb俄罗斯:维生素、补品和天然产品
2020/07/09 全球购物
毕业生造价工程师求职信
2013/10/17 职场文书
英文版销售经理个人求职信
2013/11/20 职场文书
三八节主持词
2014/03/17 职场文书
机械电子工程专业自荐书
2014/06/10 职场文书
政府法律服务方案
2014/06/14 职场文书
工会优秀工作者事迹
2014/08/17 职场文书
班子成员四风问题自我剖析材料
2014/09/29 职场文书
法学专业大学生实习自我鉴定
2014/10/05 职场文书
小学六一儿童节活动开幕词
2016/03/04 职场文书
2019年教师节:送给所有老师的祝福语
2019/09/05 职场文书
话题作文之成长
2019/12/09 职场文书
vue实现Toast组件轻提示
2022/04/10 Vue.js