Bacysoft.cn

 找回密码
 邀请注册
查看: 37653|回复: 0
打印 上一主题 下一主题

Discuz!X3.2 Ajax 操作详解及实例(一):ajaxget()

[复制链接]
跳转到指定楼层
楼主
发表于 2015-9-3 18:36:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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 文件中,参见以下两段源码:
  1. // Line:510, Common.js
  2. function ajaxget(url, showid, waitid, loading, display, recall) {
  3.         $F('_ajaxget', arguments, 'ajax');
  4. }
复制代码
而实现实际功能的代码位于 ajax.js 文件的第8行:
  1. // Line:8, Ajax.js
  2. function _ajaxget(url, showid, waitid, loading, display, recall) {
  3. /* ... */
  4. }
复制代码
在 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 中的代码:
  1. <?php

  2. $act = $_GET['act'];

  3. switch ($act) {
  4.         case 'ajaxgetstring':

复制代码
2.1.2、主模板 test.htm 代码如下:
  1. {template common/header}

  2. <a href="plugin.php?id=test&act=ajaxgetstring" onclick="ajaxget(this.href, 'strbox'); return false;">
  3.         Click Me
  4. </a>
  5. <span id="strbox" style="color:red;"></span>

  6. {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 进行处理,代码如下:
  1. var url = url + '&inajax=1&ajaxtarget=' + showid;
复制代码
也就是说 ajaxget 会给传入的 url 加上两个参数 inajax 和 ajaxtarget,inajax 为 1 表示这是一个 ajax 请求,ajaxtarget 表示回显信息的 HTML 容器元素 ID;当服务端 Discuz 内核检测到参数 inajax 为真时会对输出到客户端的信息做特殊处理,主要表现在加载模板的时候;请回顾 test.inc.php 中输出 FORMHASH 的代码:
  1.   include template('common/header');
  2.                 echo FORMHASH;
  3.                 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 文件格式的头部和尾部, 因此实际输出的内容就变成:
  1. <?xml version="1.0" encoding="'.CHARSET.'"?>
  2. <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 函数的参数,修改后代码如下:
  1. 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 的部分,参考代码如下:
  1. <script>
  2. function ajaxget_recall() {
  3.         alert('ajaxget_recall');
  4. }
  5. </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',参考代码如下:
  1. {template common/header}

  2. <a href="plugin.php?id=test&act=ajaxgetscript" onclick="ajaxget(this.href, 'strbox'); return false;">
  3.         Click Me
  4. </a>
  5. <span id="strbox" style="color:red;"></span>

  6. {template common/footer}
复制代码
2.3.2、test.inc.php 中增加 'ajaxgetscript' 分支,参考代码如下:
  1. case 'ajaxgetscript':

  2.                 $str = <<<EOF
  3. Will Alert: OMG!
  4. <script reload="1">
  5. function alertstr() {
  6.         alert('OMG!');
  7. }
  8. alertstr();
  9. </script>
  10. EOF;

  11.                 include template('common/header');
  12.                 echo $str;
  13.                 include template('common/footer');

  14.                 exit;
复制代码
2.3.3、本例与实例二功能类似,可以根据实际情况灵活选择。唯一一点区别在于,本例中 script 标签中包含一个 reload 属性,如果 reload 值为真,则代表此 script 可以在页面上多次执行,如果为假,则只有在 ajaxget 第一次在 showid 所指向的 HTML 容器中输出返回值时才执行,后续重复点击 A 标签将不会再执行 script 标签中的 JS 代码;

本节完
您需要登录后才可以回帖 登录 | 邀请注册

本版积分规则



京ICP备08000958号-1|腾讯云|阿里云|联系方式|Bacysoft.cn

GMT+8, 2024-12-25 15:16 , Processed in 0.013727 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表