Bacysoft.cn
标题:
Discuz!X3.2 Ajax 操作详解及实例(一):ajaxget()
[打印本页]
作者:
bacy001
时间:
2015-9-3 18:36
标题:
Discuz!X3.2 Ajax 操作详解及实例(一):ajaxget()
本帖最后由 bacy001 于 2015-9-3 21:19 编辑
ajaxget() 与 ajaxpost() 函数是 Discuz!X 系统前端部分很重要的函数,两者在整个源码中有几百处调用,是 Discuz!X 系统中最主要的 Ajax 实现。
本文将详细介绍 ajaxget() 函数,下一篇将介绍 ajaxpost() 函数,本系列教程基于 Discuz!X3.2 版本介绍,相对与 X2.5 版本来说 Ajax 部分没有本质变化,有关 X2.5 部分的内容,可以参考:
Discuz!X 源码分析之 ajaxget() 函数
Discuz!X 源码分析之 ajaxpost() 函数
1、函数简析
在 X3.2 版本中,ajaxget() 函数的定义依旧是放在 common.js 文件中,但是实现实际功能的代码已经移动到 ajax.js 文件中,参见以下两段源码:
// Line:510, Common.js
function ajaxget(url, showid, waitid, loading, display, recall) {
$F('_ajaxget', arguments, 'ajax');
}
复制代码
而实现实际功能的代码位于 ajax.js 文件的第8行:
// Line:8, Ajax.js
function _ajaxget(url, showid, waitid, loading, display, recall) {
/* ... */
}
复制代码
在 Common.js 中函数 $F() 的功能是动态加载 js 文件,第一个参数是目标 js 文件中将要调用的函数名,第二个参数是将要传递给被调用函数的参数,第三个函数指明将要加载的 js 文件名。而在 X2.5 以及以前版本,ajaxget 的执行部分是直接写在 Common.js 文件中。
参数说明:
url(必填),ajax 对象将要访问的服务端 url;
showid(必填),ajax 对象获取到服务端返回值以后,用于显示返回值的 HTML 容器元素的 ID;
waitid,ajax 对象执行过程中,用于显示等待信息的 HTML 容器元素的 ID,默认值等于 showid 的值;
loading,ajax 对象执行过程中,用于显示在 waitid 所指向的 HTML 容器元素中的内容,默认值为“请稍后”;
display,服务端信息返回后 showid 的 style.display 值,如果设置为'none',则信息将不会显示在页面上;
recall,回调 js,即信息成功返回后将会执行的前端 js 函数名称;
2、应用实例
本教程所有实例均假设运行于 Discuz!X 插件当中。
假设插件的 pluginid 为:test;
则此插件的访问 URL 为:http://yourdomain/plugin.php?id=test
插件主模块文件名:./source/plugin/test/test.inc.php
插件模板主要页面:./source/plugin/test/template/test.htm
2.1、实例一
:在插件中使用 ajaxget() 从服务端获取文本内容,并显示在页面的指定区域;
2.1.1、test.inc.php 中的代码:
<?php
$act = $_GET['act'];
switch ($act) {
case 'ajaxgetstring':
复制代码
2.1.2、主模板 test.htm 代码如下:
{template common/header}
<a href="plugin.php?id=test&act=ajaxgetstring" onclick="ajaxget(this.href, 'strbox'); return false;">
Click Me
</a>
<span id="strbox" style="color:red;"></span>
{template common/footer}
复制代码
2.1.3、代码运行流程
2.1.3.1、浏览器上访问插件地址后,开始执行 test.inc.php 中的代码;
首先判断 URL 是否包含参数 act,如果没有,则调用模板文件 test.htm;
如果 act 值为 '
ajaxgetstring',则在睡眠 2 秒后向客户端输出 FORMHASH 的值,并退出;
2.1.3.2、模板文件中除包含 Discuz 默认的头部和尾部模板外(必须包含,特别头部模板中加载了 common.js 库),只有一个 <a> 标签 和 <span> 标签;
其中 A 标签的 onclick 事件中调用了 ajaxget 函数,两个参数分别是 A 标签的 href 属性值和 SPAN 标签的 ID 值,意思是 ajaxget 将发送请求到 this.href,并将返回值显示在 SPAN 标签中;
2.1.3.3、当点击页面上的 A 标签后,会立即进入 ajaxget 函数执行,函数体首先处理相关的参数,其中比较重要的是对 url 进行处理,代码如下:
var url = url + '&inajax=1&ajaxtarget=' + showid;
复制代码
也就是说 ajaxget 会给传入的 url 加上两个参数 inajax 和 ajaxtarget,inajax 为 1 表示这是一个 ajax 请求,ajaxtarget 表示回显信息的 HTML 容器元素 ID;当服务端 Discuz 内核检测到参数 inajax 为真时会对输出到客户端的信息做特殊处理,主要表现在加载模板的时候;请回顾 test.inc.php 中输出 FORMHASH 的代码:
include template('common/header');
echo FORMHASH;
include template('common/footer');
复制代码
按代码理解,这里加载的应该是模板文件: common/header.htm 和 common/footer.htm;但实际上,因为 inajax 为真的原因,template() 函数实际加载的模板是: common/header_ajax.htm 和 common/footer_ajax.htm;这两者的区别是 header 和 footer 是标准的头部和尾部模板,而 header_ajax 和 footer_ajax 实际上是 xml 文件格式的头部和尾部, 因此实际输出的内容就变成:
<?xml version="1.0" encoding="'.CHARSET.'"?>
<root><![CDATA[FORMHASH]]></root>
复制代码
只有按照这种格式输出的内容,才能被 ajaxget 客户端正确提取。
2.1.3.4、A 标签 onclick 事件中在 ajaxget 调用后面的 return false; 是必须的,如果缺少了这个 return,点击 A 标签后会按照正常的非 ajax 调用访问 href 指向的 URL,因此必须返回 false,以阻止这种情况发生。
2.2、实例二
:在实例一的基础上加上回调 js,即客户端接收到返回信息后自动执行指定的 js 函数;
2.2.1、修改 test.htm 中 A 标签 onclick 事件中 ajaxget 函数的参数,修改后代码如下:
ajaxget(this.href, 'strbox','strbox','Just Wait a Moment!','', ajaxget_recall)
复制代码
参数对应关系如下:
url =>
this.href,
showid => '
strbox',
waitid => '
strbox',
loading => '
Just Wait a Moment!',
display => '',
recall =>
ajaxget_recall,
2.2.2、在 test.htm 中增加 JS 函数
ajaxget_recall 的部分,参考代码如下:
<script>
function ajaxget_recall() {
alert('ajaxget_recall');
}
</script>
复制代码
2.2.3、代码分析
先看看 ajaxget 中新加的参数,其中 loading 表示 ajaxget 发送请求到等待返回值的过程中显示在 waitid 指向的 HTML 容器元素中的内容,默认显示中文“请稍等”,此例中将显示为:Just Wait a Moment!
再看 recall,当 ajaxget 正确接收到服务端发回的返回值后就会调用 Js 函数
ajaxget_recall()。
2.3、实例三
:服务端返回值中直接包含 JS 脚本并执行;
2.3.1、修改 test.htm 中 A 标签的 href 值,将 'ajaxgetstring' 替换成 'ajaxgetscript',参考代码如下:
{template common/header}
<a href="plugin.php?id=test&act=ajaxgetscript" onclick="ajaxget(this.href, 'strbox'); return false;">
Click Me
</a>
<span id="strbox" style="color:red;"></span>
{template common/footer}
复制代码
2.3.2、test.inc.php 中增加 'ajaxgetscript' 分支,参考代码如下:
case 'ajaxgetscript':
$str = <<<EOF
Will Alert: OMG!
<script reload="1">
function alertstr() {
alert('OMG!');
}
alertstr();
</script>
EOF;
include template('common/header');
echo $str;
include template('common/footer');
exit;
复制代码
2.3.3、本例与实例二功能类似,可以根据实际情况灵活选择。唯一一点区别在于,本例中 script 标签中包含一个 reload 属性,如果 reload 值为真,则代表此 script 可以在页面上多次执行,如果为假,则只有在 ajaxget 第一次在 showid 所指向的 HTML 容器中输出返回值时才执行,后续重复点击 A 标签将不会再执行 script 标签中的 JS 代码;
本节完
欢迎光临 Bacysoft.cn (http://bacysoft.cn/)
Powered by Discuz! X3.3