利用 ajax 制作简单的边栏日历插件

这回写了个 Typecho 边栏日历插件,这是本人第一次写博客插件

链接:https://github.com/istobran/typecho-calender-plugin

在做这个插件的时候,由于是第一次上手玩 Typecho 插件,遇到了很多很多的问题

先是一点一点的去分析别人写的插件,搞清楚了 plugin.php 的工作机制,再根据分析结果把自己的代码注入进去

还好自己还有一点这方面的功底,分析过程还算顺利,接着自己写的日历的 HTML 结构和 CSS 样式很快就搞定了

在实现日历翻页功能的时候,本来可以用纯 javascript 去实现的,但是想了想,还是试一下 ajax 吧

于是就开始着手研究自己从来没接触过的 ajax,下面就开始记录一下自己的学习成果

Ajax 的英文全称是 Asynchronous JavaScript and XML(参考 wiki 上的定义 https://zh.wikipedia.org/wiki/AJAX

直译的话就是异步的 javascript 和 XML,也就是说,ajax 本身是实现异步交互的一种技术

关于异步的概念,可以参考这里:http://www.cnblogs.com/zhangjing0502/archive/2012/05/18/2507786.html

这里也说下我对异步这个概念的理解吧,异步这个概念事实上是相对于同步而言的

也就是说,异步技术是用来解决同步技术中存在的缺点的

那么同步技术中所存在的问题有哪些呢?

事实上从业务逻辑的角度上来说是没有问题的。问题主要出现在用户体验上

比如用户注册功能,传统的同步技术使用户必须填完所有表单之后才能提交

服务器对表单处理完成后,再返回结果给用户,成功的还好说

但是如果说,这个用户名已经被占用了的话,用户需要再重新填写整个注册表单

而且用户没有办法保证提交了表单之后就不出错。

为了解决这个问题,人们设想,能不能让用户一边填的时候,一边验证呢?

于是异步请求的技术就产生了,它使得页面能在不重新加载的前提下,与服务器进行通信。把验证结果直接反馈到当前页面上

ajax 就是这么一个技术,他从技术层面上实现了一边填写表单一边验证的过程

ajax 通过使用 javascript 发送 xml 数据给服务器,服务器再把结果返回回来,实现基于 xml 内容格式的通信

下面是一个 XML 请求的构建过程

1、实例化一个 XMLHttpRequest 对象

1
var request = new XMLHttpRequest();

2、设定 url 和请求方式(以 GET 请求为例)

1
request.open("GET", "server.php?number=" + document.getElementById("keyword").value);

3、发送请求

1
request.send();

4、监听请求的状态变化

1
2
3
4
5
6
7
8
9
10
11
request.onreadystatechange = function() {
if (request.readyState===4) { // 表示请求完成,且响应已经就绪
if (request.status===200) {
// 表明请求成功,返回 HTTP 状态码 200
document.getElementById("searchResult").innerHTML = request.responseText;
} else {
// 表明请求失败,返回了其他的状态码
alert("发生错误:" + request.status);
}
}
}

以上就是一个完整的 ajax 请求过程,通过构建请求并监听 request 的状态变化,即可实现页面异步处理的过程

关于 readyState 的值的含义:

1
2
3
4
5
6
readyState 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪

构建 POST 请求也只是大同小异,在构建 XMLHTTPRequest 请求的时候修改一下发送方式即可

1
2
3
4
5
6
7
8
var request = new XMLHttpRequest();
request.open("POST", "server.php");
var data = "name=" + document.getElementById("staffName").value
+ "&number=" + document.getElementById("staffNumber").value
+ "&sex=" + document.getElementById("staffSex").value
+ "&job=" + document.getElementById("staffJob").value;
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
request.send(data);

以上就是一个较为原始的 ajax 的实现方式了,值得注意的是,POST 方式的请求必须设置 HTTP 请求头的 Content-type,否则服务器端可能无法识别

不过上面这种服务器直接返回 HTML 的做法现在已经比较少使用了

现在更加普遍的一种做法是,发送请求的时候依然使用 XML,但服务器会返回 json 数据

所以在处理响应的时候,经常会用到 json 解析函数

下面是一个处理 JSON 的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
request.onreadystatechange = function() {
if (request.readyState===4) {
if (request.status===200) {
var data = JSON.parse(request.responseText);
if (data.success) {
document.getElementById("createResult").innerHTML = data.msg;
} else {
document.getElementById("createResult").innerHTML = "出现错误:" + data.msg;
}
} else {
alert("发生错误:" + request.status);
}
}
}

可以看到,上面使用了 JSON.parse 来处理 response 响应中的内容(要尽量避免使用 eval,因为 eval 是不安全的处理方式)

使用 JQuery 来构建 ajax 请求,直接绑定按钮的点击事件

jQuery.ajax 函数的语法(这个函数的功能最完整也最复杂):

1
2
3
4
5
6
7
$.ajax({
type: method,
url: url,
data: data,
success: success,
dataType: dataType
});

(参考:http://www.w3school.com.cn/jquery/ajax_ajax.asp

简写的 get 函数语法:

1
$(selector).get(url,data,success(response,status,xhr),dataType)

简写的 post 函数语法:

1
jQuery.post(url,data,success(data, textStatus, jqXHR),dataType)

我自己的应用的例子:

1
2
3
4
5
6
7
8
9
10
11
12
$.post(window.php_Url, {
year: $("#cal_year b").html(),
month: $("#cal_month b").html(),
action: direction,
selected: changeVal
}, function(data) {
if (data.success) {
$("#cal_plugin tbody").html(data.tbody);
$("#cal_year b").html(data.year);
$("#cal_month b").html(data.month);
}
}, "json");