zoukankan      html  css  js  c++  java
  • 《JavaScript 源码分析》之 jquery.unobtrusive-ajax.js

      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));
  • 相关阅读:
    Android Studio生成APK自动追加版本号
    jquery.nicescroll.min.js滚动条使用方法
    Guid.NewGuid().ToString()生成唯一码js
    解决移动端H5海报滑动插件适应大部分手机问题 手机端高度自适应
    SouthidcEditor编辑器如何支持上传png图片
    谈灰色行业网站建设需要注意的事项
    33个免费的电子商务图标集
    WebKit的已实施srcset图像响应属性
    免费清新浅色图标集
    闪光的不一定是金子:设计数据的一种常见误解
  • 原文地址:https://www.cnblogs.com/lvyongbo/p/5564667.html
Copyright © 2011-2022 走看看