QQ交流群:110826636

jquery.unobtrusive-ajax.js的扩展,做到片段式加载

  1 //ajax支持库
  2 /*!
  3 ** Unobtrusive Ajax support library for jQuery
  4 ** Copyright (C) Microsoft Corporation. All rights reserved.
  5 */
  6 
  7 /*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 */
  8 /*global window: false, jQuery: false */
  9 /*
 10 data-ajax=true //开启绑定
 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//失败,error
 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 
137     
138     $(document).on("click", "a[data-ajax=true]", function (evt) {
139         evt.preventDefault();
140         asyncRequest(this, {
141             url: this.href,
142             type: "GET",
143             data: []
144         });
145     });
146 
147     $(document).on("click", "form[data-ajax=true] input[type=image]", function (evt) {//这个不常用
148         var name = evt.target.name,
149             $target = $(evt.target),
150             form = $target.parents("form")[0],
151             offset = $target.offset();
152 
153         $(form).data(data_click, [
154             { name: name + ".x", value: Math.round(evt.pageX - offset.left) },
155             { name: name + ".y", value: Math.round(evt.pageY - offset.top) }
156         ]);
157 
158         setTimeout(function () {
159             $(form).removeData(data_click);
160         }, 0);
161     });
162 
163     $(document).on("click", "form[data-ajax=true] :submit", function (evt) {
164         var name = evt.target.name,
165             form = $(evt.target).parents("form")[0];
166 
167         $(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []);
168 
169         setTimeout(function () {
170             $(form).removeData(data_click);
171         }, 0);
172     });
173 
174     $(document).on("submit", "form[data-ajax=true]", function (evt) {
175         var clickInfo = $(this).data(data_click) || [];
176         evt.preventDefault();
177         if (!validate(this)) {
178             return;
179         }
180         asyncRequest(this, {
181             url: this.action,
182             type: this.method || "GET",
183             data: clickInfo.concat($(this).serializeArray())//写得好,序列化表单并拼接,以后的ajax都可以这样,方便啊
184         });
185     });
186     //扩展
187     function bindDataAjax(obj) {
188         $(obj).on("click", "a[data-ajax=true]", function (evt) {
189             evt.preventDefault();
190             asyncRequest(this, {
191                 url: this.href,
192                 type: "GET",
193                 data: []
194             });
195         });
196 
197         $(obj).on("click", "form[data-ajax=true] input[type=image]", function (evt) {//这个不常用
198             var name = evt.target.name,
199                 $target = $(evt.target),
200                 form = $target.parents("form")[0],
201                 offset = $target.offset();
202 
203             $(form).data(data_click, [
204                 { name: name + ".x", value: Math.round(evt.pageX - offset.left) },
205                 { name: name + ".y", value: Math.round(evt.pageY - offset.top) }
206             ]);
207 
208             setTimeout(function () {
209                 $(form).removeData(data_click);
210             }, 0);
211         });
212 
213         $(obj).on("click", "form[data-ajax=true] :submit", function (evt) {
214             var name = evt.target.name,
215                 form = $(evt.target).parents("form")[0];
216 
217             $(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []);
218 
219             setTimeout(function () {
220                 $(form).removeData(data_click);
221             }, 0);
222         });
223 
224         $(obj).on("submit", "form[data-ajax=true]", function (evt) {
225             var clickInfo = $(this).data(data_click) || [];
226             evt.preventDefault();
227             if (!validate(this)) {
228                 return;
229             }
230             asyncRequest(this, {
231                 url: this.action,
232                 type: this.method || "GET",
233                 data: clickInfo.concat($(this).serializeArray())//写得好,序列化表单并拼接,以后的ajax都可以这样,方便啊
234             });
235         });
236     }
237     $.fn.unobtrusive = function (option, param) {
238         if (typeof options == "string") {
239             return $.fn.unobtrusive.methods[options](this, param);
240         }
241         
242     }
243     //方法
244     $.fn.unobtrusive.methods = {
245         resetbind: function (jq) {//对应的对象重新初始化
246             return jq.each(function () {
247                 //bindDataAjax($(this), obj);
248                 //bindDataAjax(obj);
249                 bindDataAjax(jq);
250             });
251         }
252     }
253 }(jQuery));

在出现//扩展字样的地方开始就是我写的扩展,不妨碍原先的代码(尽量不修改别人的代码是我的原则,也是对别人的尊重)。函数主要是提供指定区域的代码绑定,使用方法

$(obj).unobtrusive('resetbind')

需要绑定的地方的DOM对象绑定。比如片段式加载一个页面

<a href="javascript:;" data-ajax-mode="" data-ajax-update=".down-content" data-ajax="true" data-ajax-method="get" data-ajax-url="/Admin/UserAdd" data-ajax-loading="#load"  data-ajax-success="$('.down-content').unobtrusive('resetbind')">添加</a>

将Ajax后的代码加载到.down-content的容器内,然后渲染绑定他们(其实如UI中的easyui也是这样干的)

在片段式加载的方法中我提及一下jquery的load也可以实现,我之前再博客中开源的MvcAdmin就是使用load,但是归根结底还是jquery的html方法。load内部就是对Ajax的封装,然后用html加载到页面上去,load的源码中好像这样写的http://www.css88.com/tool/jQuerySourceViewer/#v=1.7.2&fn=jQuery.fn.load

特别提醒

data-ajax-begin//ajax前触发的函数或者一段程序

data-ajax-complete//完成后,此时还没有加载返回的数据,请求成功或失败时均调用

data-ajax-success//成功,加载完成的数据

这三个的参数的调用的函数必须是字符串,不需要()。比如data-ajax-begin="函数名",不是data-ajax-begin="函数名()",对,不需要括号!

posted @ 2015-06-01 08:41  FourOne  阅读(593)  评论(0编辑  收藏  举报