1. /*!
  2. ** Unobtrusive Ajax support library for jQuery
  3. ** Copyright (C) Microsoft Corporation. All rights reserved.
  4. */
  5.  
  6. /*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
  7. /*global window: false, jQuery: false */
  8. /*
  9. data-ajax=true //开启绑定
  10.  
  11. data-ajax-mode//更新的形式 BEFORE插入到对象之前 AFTER插入到对象之后 为空就是覆盖
  12. data-ajax-update//更新的对象
  13. data-ajax-confirm//设置一个确定取消弹出框的文字,没有则不设置
  14. data-ajax-loading//显示loading的对象
  15. data-ajax-loading-duration//持续时间 默认是0
  16. data-ajax-method//提交方式
  17. data-ajax-url//提交url
  18. data-ajax-begin//ajax前触发的函数或者一段程序
  19. data-ajax-complete//完成后,此时还没有加载返回的数据,请求成功或失败时均调用
  20. data-ajax-success//成功,加载完成的数据
  21. data-ajax-failure//失败
  22.  
  23. */
  24.  
  25. (function ($) {
  26. var data_click = "unobtrusiveAjaxClick",
  27. data_validation = "unobtrusiveValidation";
  28. //第二核心,判断是否函数,不是则构造一个匿名函数
  29. function getFunction(code, argNames) {
  30. var fn = window, parts = (code || "").split(".");
  31. while (fn && parts.length) {
  32. fn = fn[parts.shift()];
  33. }//查找函数名有时候是命名空间比如xxx.xxx
  34. if (typeof (fn) === "function") {
  35. return fn;
  36. }
  37. argNames.push(code);
  38. //如果不是函数对象则自己构造一个并返回,吊!
  39. return Function.constructor.apply(null, argNames);
  40. }
  41.  
  42. function isMethodProxySafe(method) {
  43. return method === "GET" || method === "POST";
  44. }
  45. //可以添加各种提交方式,应该是为Web Api做的补充
  46. function asyncOnBeforeSend(xhr, method) {
  47. if (!isMethodProxySafe(method)) {
  48. xhr.setRequestHeader("X-HTTP-Method-Override", method);
  49. }
  50. //注:X-HTTP-Method-Override是一个非标准的HTTP报头。
  51. //这是为不能发送某些HTTP请求类型(如PUT或DELETE)的客户端而设计的
  52. }
  53. //完成后的
  54. function asyncOnSuccess(element, data, contentType) {
  55. var mode;
  56.  
  57. if (contentType.indexOf("application/x-javascript") !== -1) { // jQuery already executes JavaScript for us
  58. return;
  59. }
  60.  
  61. mode = (element.getAttribute("data-ajax-mode") || "").toUpperCase();
  62. $(element.getAttribute("data-ajax-update")).each(function (i, update) {
  63. var top;
  64.  
  65. switch (mode) {
  66. case "BEFORE":
  67. top = update.firstChild;
  68. $("<div />").html(data).contents().each(function () {
  69. update.insertBefore(this, top);
  70. });
  71. break;
  72. case "AFTER":
  73. $("<div />").html(data).contents().each(function () {
  74. update.appendChild(this);
  75. });
  76. break;
  77. default:
  78. $(update).html(data);
  79. break;
  80. }
  81. });
  82. }
  83. //主要函数
  84. //绑定的对象和参数
  85. function asyncRequest(element, options) {
  86. var confirm, loading, method, duration;
  87.  
  88. confirm = element.getAttribute("data-ajax-confirm");
  89. if (confirm && !window.confirm(confirm)) {
  90. return;
  91. }
  92.  
  93. loading = $(element.getAttribute("data-ajax-loading"));//
  94. duration = element.getAttribute("data-ajax-loading-duration") || 0;//默认是0
  95.  
  96. $.extend(options, {
  97. type: element.getAttribute("data-ajax-method") || undefined,
  98. url: element.getAttribute("data-ajax-url") || undefined,
  99. beforeSend: function (xhr) {//ajax前触发,此处的xhr将在下面用apply传递出去
  100. var result;
  101. asyncOnBeforeSend(xhr, method);//判断是否添加特种的提交方式
  102. result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(this, arguments);//argument:替换函数对象的其中一个属性对象,存储参数。这里是将原先的参数传递出去,吊!
  103. if (result !== false) {
  104. loading.show(duration);
  105. }
  106. return result;
  107. },
  108. complete: function () {
  109. loading.hide(duration);
  110. getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(this, arguments);
  111. },
  112. success: function (data, status, xhr) {
  113. asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html");
  114. getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(this, arguments);
  115. },
  116. error: getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"])
  117. });
  118.  
  119. options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" });
  120.  
  121. method = options.type.toUpperCase();//大写
  122. if (!isMethodProxySafe(method)) {
  123. options.type = "POST";
  124. options.data.push({ name: "X-HTTP-Method-Override", value: method });
  125. }
  126. //最后都是调用jquery的ajax
  127. $.ajax(options);
  128. }
  129.  
  130. function validate(form) {
  131. //可以取消验证
  132. var validationInfo = $(form).data(data_validation);
  133. return !validationInfo || !validationInfo.validate || validationInfo.validate();
  134. }
  135.  
  136. $(document).on("click", "a[data-ajax=true]", function (evt) {
  137. evt.preventDefault();
  138. asyncRequest(this, {
  139. url: this.href,
  140. type: "GET",
  141. data: []
  142. });
  143. });
  144.  
  145. $(document).on("click", "form[data-ajax=true] input[type=image]", function (evt) {//这个不常用
  146. var name = evt.target.name,
  147. $target = $(evt.target),
  148. form = $target.parents("form")[0],
  149. offset = $target.offset();
  150.  
  151. $(form).data(data_click, [
  152. { name: name + ".x", value: Math.round(evt.pageX - offset.left) },
  153. { name: name + ".y", value: Math.round(evt.pageY - offset.top) }
  154. ]);
  155.  
  156. setTimeout(function () {
  157. $(form).removeData(data_click);
  158. }, 0);
  159. });
  160.  
  161. $(document).on("click", "form[data-ajax=true] :submit", function (evt) {
  162. var name = evt.target.name,
  163. form = $(evt.target).parents("form")[0];
  164.  
  165. $(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []);
  166.  
  167. setTimeout(function () {
  168. $(form).removeData(data_click);
  169. }, 0);
  170. });
  171.  
  172. $(document).on("submit", "form[data-ajax=true]", function (evt) {
  173. var clickInfo = $(this).data(data_click) || [];
  174. evt.preventDefault();
  175. if (!validate(this)) {
  176. return;
  177. }
  178. asyncRequest(this, {
  179. url: this.action,
  180. type: this.method || "GET",
  181. data: clickInfo.concat($(this).serializeArray())//写得好,序列化表单并拼接,以后的ajax都可以这样,方便啊
  182. });
  183. });
  184. }(jQuery));

基本上想注释的都注释了一遍,我反正被这180行的代码折服了。很不错!

jquery.unobtrusive-ajax.js源码阅读的更多相关文章

  1. Three.js源码阅读笔记-5

    Core::Ray 该类用来表示空间中的“射线”,主要用来进行碰撞检测. THREE.Ray = function ( origin, direction ) { this.origin = ( or ...

  2. Dom7.js 源码阅读备份

    在Framework7,其特色的HTML框架,可以创建精美的iOS应用;  她有自己的 DOM7- 一个集成了大部分常用DOM操作的高性能库.你不需要学习任何新的东西,因为她的用法和大名鼎鼎的jQue ...

  3. underscore.js 源码阅读 准备

    本次阅读是初次阅读源码,参考了以下几篇文章: https://github.com/hanzichi?language=javascript&page=5&tab=stars http ...

  4. underscore.js,jquery.js源码阅读

    (function() { // Baseline setup // -------------- // Establish the root object, `window` in the brow ...

  5. 关于jQuery的ajax的源码的dataType解读

    $.ajax其实底层还是用的XMLHttpRequest,对于加载数据的格式datatype有:xml.text.html.json.jsonp.script. 其中xml.text不需要处理,直接使 ...

  6. flipsnap.js 源码阅读备份

    这是官网:http://hokaccha.github.io/js-flipsnap/ 1.引入全局命名空间 类似jQuery插件写法   传入window, document,提高内部访问速度: ; ...

  7. jQuery插件pagination.js源码解读

    pagination的github地址:https://github.com/gbirke/jquery_pagination 公司用的是1.2的版本,所以我就读1.2的了. jQuery.fn.pa ...

  8. underscore.js 源码阅读 一 整体结构

    // 整个underscore的实现包在一个立即执行函数中,避免污染全局对象 // 通过call(this)来入全局变量 (function() { // 缓存this var root = this ...

  9. 【 js 基础 】【 源码学习 】backbone 源码阅读(二)

    最近看完了 backbone.js 的源码,这里对于源码的细节就不再赘述了,大家可以 star 我的源码阅读项目(source-code-study)进行参考交流,有详细的源码注释,以及知识总结,同时 ...

随机推荐

  1. 用C#编写游戏脚本

    大学宿舍玩游戏的时候,为了简化重复的键鼠动作,有学习过按键精灵和TC脚本开发工具,并做了一些小脚本,基本达到了当时的需求.不知不觉,已经毕业了3年了,无聊之余又玩起了游戏,对于一些无趣的重复行为,于是 ...

  2. 关于AIR新浪登录测试

    /** *由于在应用申请中,我设置的域名属于新浪云,因此在本地测试的话肯定不能成功的,有个办法就是直接在新浪云那边授权成功后,将token的值直接使用post或者get方法传递过来,直接在本地 *lo ...

  3. DB2命令大全

    1.1查看表空间 db2 list tablespaces show detail 1.2查看数据库的表死锁 方法一: 打开监控   db2 update monitor switches using ...

  4. Python批量插入SQL Server数据库

    因为要做性能测试,需要大量造数据到数据库中,于是用python写了点代码去实现,批量插入,一共四张表 简单粗暴地插入10万条数据 import pymssql import random __auth ...

  5. robotframework+ride+Selenium2Library+AutoItLibrary配置

    最近要安装RFS,虽然网上很多安装说明,但是自己装的时候还是遇到了很多问题. 1. AutoLibrary导入失败:猜测原因是AutoLibrary需要先安装pywin32,而我一开始安装的是pyth ...

  6. 关于javax.servlet.jsp.JspTagException: Don't know how to iterate over supplied "items" in &lt;forEach&gt;

    今天遇到这样一个异常: 严重: Servlet.service() for servlet jsp threw exceptionjavax.servlet.jsp.JspTagException: ...

  7. NOIP2004 虫食算

    描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子:43#9865#045+ 8468#6633= 44445506678其中#号代表 ...

  8. Sublime Text 2 配置及其使用

    如果说Notepad++是一款不错Code神器,那么Sublime Text应当称得上是神器滴哥. Sublime Text最大的优点就是跨平台,Mac和Windows均可完美使用:其次是强大的插件支 ...

  9. C# 操作XML 如果不存在创建 存在直接追加

    #region 写操作日志----------------这种格式 //<Log 操作人="Admin" 操作结果="成功" 结果详情="数据导 ...

  10. mount挂载

    与ln -s 功能类似 # mount --bind /data/public /home/user/public /etc/fstab # <file system> <mount ...