《JavaScript 源码分析》之 jquery.unobtrusive-ajax.js
/*!
** Unobtrusive Ajax support library for jQuery
** Copyright (C) Microsoft Corporation. All rights reserved.
*/ /*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 */
/*global window: false, jQuery: false */
/*
data-ajax=true //开启绑定 data-ajax-mode//更新的形式 BEFORE插入到对象之前 AFTER插入到对象之后 为空就是覆盖
data-ajax-update//更新的对象
data-ajax-confirm//设置一个确定取消弹出框的文字,没有则不设置
data-ajax-loading//显示loading的对象
data-ajax-loading-duration//持续时间 默认是0
data-ajax-method//提交方式
data-ajax-url//提交url
data-ajax-begin//ajax前触发的函数或者一段程序
data-ajax-complete//完成后,此时还没有加载返回的数据,请求成功或失败时均调用
data-ajax-success//成功,加载完成的数据
data-ajax-failure//失败 */ (function ($) {
var data_click = "unobtrusiveAjaxClick",
data_validation = "unobtrusiveValidation";
//第二核心,判断是否函数,不是则构造一个匿名函数
function getFunction(code, argNames) {
var fn = window, parts = (code || "").split(".");
while (fn && parts.length) {
fn = fn[parts.shift()];
}//查找函数名有时候是命名空间比如xxx.xxx
if (typeof (fn) === "function") {
return fn;
}
argNames.push(code);
//如果不是函数对象则自己构造一个并返回,吊!
return Function.constructor.apply(null, argNames);
} function isMethodProxySafe(method) {
return method === "GET" || method === "POST";
}
//可以添加各种提交方式,应该是为Web Api做的补充
function asyncOnBeforeSend(xhr, method) {
if (!isMethodProxySafe(method)) {
xhr.setRequestHeader("X-HTTP-Method-Override", method);
}
//注:X-HTTP-Method-Override是一个非标准的HTTP报头。
//这是为不能发送某些HTTP请求类型(如PUT或DELETE)的客户端而设计的
}
//完成后的
function asyncOnSuccess(element, data, contentType) {
var mode; if (contentType.indexOf("application/x-javascript") !== -1) { // jQuery already executes JavaScript for us
return;
} mode = (element.getAttribute("data-ajax-mode") || "").toUpperCase();
$(element.getAttribute("data-ajax-update")).each(function (i, update) {
var top; switch (mode) {
case "BEFORE":
top = update.firstChild;
$("<div />").html(data).contents().each(function () {
update.insertBefore(this, top);
});
break;
case "AFTER":
$("<div />").html(data).contents().each(function () {
update.appendChild(this);
});
break;
default:
$(update).html(data);
break;
}
});
}
//主要函数
//绑定的对象和参数
function asyncRequest(element, options) {
var confirm, loading, method, duration; confirm = element.getAttribute("data-ajax-confirm");
if (confirm && !window.confirm(confirm)) {
return;
} loading = $(element.getAttribute("data-ajax-loading"));//
duration = element.getAttribute("data-ajax-loading-duration") || 0;//默认是0 $.extend(options, {
type: element.getAttribute("data-ajax-method") || undefined,
url: element.getAttribute("data-ajax-url") || undefined,
beforeSend: function (xhr) {//ajax前触发,此处的xhr将在下面用apply传递出去
var result;
asyncOnBeforeSend(xhr, method);//判断是否添加特种的提交方式
result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(this, arguments);//argument:替换函数对象的其中一个属性对象,存储参数。这里是将原先的参数传递出去,吊!
if (result !== false) {
loading.show(duration);
}
return result;
},
complete: function () {
loading.hide(duration);
getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(this, arguments);
},
success: function (data, status, xhr) {
asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html");
getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(this, arguments);
},
error: getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"])
}); options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" }); method = options.type.toUpperCase();//大写
if (!isMethodProxySafe(method)) {
options.type = "POST";
options.data.push({ name: "X-HTTP-Method-Override", value: method });
}
//最后都是调用jquery的ajax
$.ajax(options);
} function validate(form) {
//可以取消验证
var validationInfo = $(form).data(data_validation);
return !validationInfo || !validationInfo.validate || validationInfo.validate();
} $(document).on("click", "a[data-ajax=true]", function (evt) {
evt.preventDefault();
asyncRequest(this, {
url: this.href,
type: "GET",
data: []
});
}); $(document).on("click", "form[data-ajax=true] input[type=image]", function (evt) {//这个不常用
var name = evt.target.name,
$target = $(evt.target),
form = $target.parents("form")[0],
offset = $target.offset(); $(form).data(data_click, [
{ name: name + ".x", value: Math.round(evt.pageX - offset.left) },
{ name: name + ".y", value: Math.round(evt.pageY - offset.top) }
]); setTimeout(function () {
$(form).removeData(data_click);
}, 0);
}); $(document).on("click", "form[data-ajax=true] :submit", function (evt) {
var name = evt.target.name,
form = $(evt.target).parents("form")[0]; $(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []); setTimeout(function () {
$(form).removeData(data_click);
}, 0);
}); $(document).on("submit", "form[data-ajax=true]", function (evt) {
var clickInfo = $(this).data(data_click) || [];
evt.preventDefault();
if (!validate(this)) {
return;
}
asyncRequest(this, {
url: this.action,
type: this.method || "GET",
data: clickInfo.concat($(this).serializeArray())//写得好,序列化表单并拼接,以后的ajax都可以这样,方便啊
});
});
}(jQuery));
《JavaScript 源码分析》之 jquery.unobtrusive-ajax.js的更多相关文章
- 一个普通的 Zepto 源码分析(二) - ajax 模块
一个普通的 Zepto 源码分析(二) - ajax 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核心模块,以 ...
- FastAdmin 源码分析:jQuery 含逗号的选择器
FastAdmin 源码分析:jQuery 含逗号的选择器 在 FastAdmin 你常常会看到以下 jQuery 选择器的代码. if ($(".datetimepicker", ...
- jQuery源码分析之=>jQuery的定义
最近写前段的代码比较多,jQuery是用的最多的一个对象,但是之前几次看了源码,都没搞清楚jQuery是怎么定义的,今天终于看明白怎么回事了.记录下来,算是一个新的开始吧. (文中源码都是jQuery ...
- 深入源码分析使用jQuery连续发起jsonp请求失败的原因
jQuery的 jsonp 大家应该是十分熟悉了.曾遇到过这样的需求1.希望请求几个相似的内容添加到页面2.请求的内容一定时间内是固定不变的,希望做个缓存. 于是脑子一拍写下了类似这样的代码 for( ...
- jQuery1.11源码分析(7)-----jQuery一些基本的API
这篇文章比较繁杂,主要就是把jQuery源码从上到下列出来,看我的注释就好了. jQuery源码对各种加载器做了处理. //阅读这个源码是请先了解一下概念,即时函数,工厂模式 (function( g ...
- jQuery1.11源码分析(6)-----jQuery结构总揽
(在看以下内容之前请先对原型链有一定的了解,比如:prototype是对象还是函数?) 在看jQuery的其他源码之前,必须对jQuery的数据结构有一定的了解. jQuery的核心很简单,jQuer ...
- jQuery 源码分析和使用心得 - core.js
core是jQuery的核心内容, 包含了最基础的方法, 比如我们常用的 $(selector, context), 用于遍历操作的 each, map, eq, first 识别变量类型的 isAr ...
- LINQ to JavaScript 源码分析
在.net平台工作一年有余,最喜欢的应属Linq特性 在几个移动端web小项目过程中,前端需要对json对象集合进行比较复杂的操作,为提高开发效率,引入了LINQ to Javascript,该项目地 ...
- jQuery 源码分析6: jQuery 基本静态方法(二)
jQuery.extend({ // 遍历obj的所有值 // args 这参数只能内部调用的会用到 // 注意到,如果回调函数调用失败会直接跳出并中止遍历 // 当有args数组时,使用apply调 ...
随机推荐
- Castle Core 4.0.0 alpha001发布
时隔一年多以后Castle 项目又开始活跃,最近刚发布了Castle Core 4.0.0 的alpha版本, https://github.com/castleproject/Core/releas ...
- ABP框架 - OData 集成
文档目录 本节内容: 简介 安装 安装Nuget包 设置模块依赖 配置你的实体 创建控制器 示例 获取实体列表 请求 响应 获取单个实体 请求 响应 获取单个实体及导航属性 请求 响应 查询 请求 响 ...
- .NET 基础 一步步 一幕幕[面向对象之构造函数、析构函数]
构造函数.析构函数 构造函数: 语法: //无参的构造函数 [访问修饰符] 函数名() :函数名必须与类名相同. //有参的构造函数 [访问修饰符] 函数名(参数列表):函数名必须与类名相同. 作用: ...
- Linux scp 设置nohup后台运行
Linux scp 设置nohup后台运行 1.正常执行scp命令 2.输入ctrl + z 暂停任务 3.bg将其放入后台 4.disown -h 将这个作业忽略HUP信号 5.测试会话中断,任务继 ...
- 2.WindowsServer2012R2装完的一些友好化设置
网站部署之~Windows Server | 本地部署 http://www.cnblogs.com/dunitian/p/4822808.html#iis 1.桌面图标(控制面板里面屏蔽了,得自己输 ...
- 【原创】免费申请SSL证书【用于HTTPS,即是把网站从HTTP改为HTTPS,加密传输数据,保护敏感数据】
今天公司有个网站需要改用https访问,所以就用到SSL证书.由于沃通(以前我是在这里申请的)暂停了免费的SSL证书之后,其网站推荐了新的一个网站来申请证书,所以,今天因为刚好又要申请一个证书,所以, ...
- OpenCV人脸识别LBPH算法源码分析
1 背景及理论基础 人脸识别是指将一个需要识别的人脸和人脸库中的某个人脸对应起来(类似于指纹识别),目的是完成识别功能,该术语需要和人脸检测进行区分,人脸检测是在一张图片中把人脸定位出来,完成的是搜寻 ...
- .Net语言 APP开发平台——Smobiler学习日志:手机应用的TextTabBar快速实现方式
参考页面: http://www.yuanjiaocheng.net/webapi/create-crud-api-1-put.html http://www.yuanjiaocheng.net/we ...
- 调用微信退款接口或发红包接口时出现System.Security.Cryptography.CryptographicException: 出现了内部错误 解决办法
我总结了一下出现证书无法加载的原因有以下三个 1.证书密码不正确,微信证书密码就是商户号 解决办法:请检查证书密码是不是和商户号一致 2.IIS设置错误,未加载用户配置文件 解决办法:找到网站使用的应 ...
- Android Studio 编译单个module
前期自己要把gradle环境变量配置好 在Terminal中gradle命令行编译apk 输入gradle assembleRelease 会编译全部module编译单个modulecd ./xiru ...