/*! * WADE JavaScript Library v2.0 for zepto * http://www.wadecn.com/ * auth:xiedx@asiainfo-linkage.com * Copyright 2014, WADE */ (function($){ window.Wade = $; var rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g, push=Array.prototype.push; /** * 数据总线相关 **/ var escapeRe=function (d){ return d.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1"); }; var support = { scriptEval: false }; var toString = Object.prototype.toString; $.Collection = function(allowFunctions, keyFn){ this.items = []; this.map = {}; this.keys = []; this.length = 0; this.allowFunctions = allowFunctions === true; if(keyFn){ this.getKey = keyFn; } }; $.Collection.prototype={ allowFunctions : false, add : function(key, o){ if(arguments.length == 1){ o = arguments[0]; key = this.getKey(o); } if(typeof key != 'undefined' && key !== null){ var old = this.map[key]; if(typeof old != 'undefined'){ return this.replace(key, o); } this.map[key] = o; } this.length++; this.items.push(o); this.keys.push(key); return o; }, getKey : function(o){ return o.id; }, replace : function(key, o){ if(arguments.length == 1){ o = arguments[0]; key = this.getKey(o); } var old = this.map[key]; if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){ return this.add(key, o); } var index = this.indexOfKey(key); this.items[index] = o; this.map[key] = o; return o; }, addAll : function(objs){ if(arguments.length > 1 || $.isArray(objs)){ var args = arguments.length > 1 ? arguments : objs; for(var i = 0, len = args.length; i < len; i++){ this.add(args[i]); } }else{ for(var key in objs){ if(this.allowFunctions || typeof objs[key] != 'function'){ this.add(key, objs[key]); } } } }, each : function(fn, scope){ var items = [].concat(this.items); // each safe for removal for(var i = 0, len = items.length; i < len; i++){ if(fn.call(scope || items[i], items[i], i, len) === false){ break; } } }, eachKey : function(fn, scope){ for(var i = 0, len = this.keys.length; i < len; i++){ fn.call(scope || window, this.keys[i], this.items[i], i, len); } }, find : function(fn, scope){ for(var i = 0, len = this.items.length; i < len; i++){ if(fn.call(scope || window, this.items[i], this.keys[i])){ return this.items[i]; } } return null; }, insert : function(index, key, o){ if(arguments.length == 2){ o = arguments[1]; key = this.getKey(o); } if(this.containsKey(key)){ this.suspendEvents(); this.removeKey(key); this.resumeEvents(); } if(index >= this.length){ return this.add(key, o); } this.length++; this.items.splice(index, 0, o); if(typeof key != 'undefined' && key !== null){ this.map[key] = o; } this.keys.splice(index, 0, key); return o; }, remove : function(o){ return this.removeAt(this.indexOf(o)); }, removeAt : function(index){ if(index < this.length && index >= 0){ this.length--; var o = this.items[index]; this.items.splice(index, 1); var key = this.keys[index]; if(typeof key != 'undefined'){ delete this.map[key]; } this.keys.splice(index, 1); return o; } return false; }, removeKey : function(key){ return this.removeAt(this.indexOfKey(key)); }, getCount : function(){ return this.length; }, indexOf : function(o){ return $.inArray(o,this.items); }, indexOfKey : function(key){ return $.inArray(key,this.keys); }, item : function(key){ var mk = this.map[key], item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined; return typeof item != 'function' || this.allowFunctions ? item : null; // for prototype! }, itemAt : function(index){ return this.items[index]; }, key : function(key){ return this.map[key]; }, contains : function(o){ return this.indexOf(o) != -1; }, containsKey : function(key){ return typeof this.map[key] != 'undefined'; }, clear : function(){ this.length = 0; this.items = []; this.keys = []; this.map = {}; }, first : function(){ return this.items[0]; }, last : function(){ return this.items[this.length-1]; }, _sort : function(property, dir, fn){ var i, len, dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1, //this is a temporary array used to apply the sorting function c = [], keys = this.keys, items = this.items; //default to a simple sorter function if one is not provided fn = fn || function(a, b) { return a - b; }; //copy all the items into a temporary array, which we will sort for(i = 0, len = items.length; i < len; i++){ c[c.length] = { key : keys[i], value: items[i], index: i }; } //sort the temporary array c.sort(function(a, b){ var v = fn(a[property], b[property]) * dsc; if(v === 0){ v = (a.index < b.index ? -1 : 1); } return v; }); //copy the temporary array back into the main this.items and this.keys objects for(i = 0, len = c.length; i < len; i++){ items[i] = c[i].value; keys[i] = c[i].key; } }, sort : function(dir, fn){ this._sort('value', dir, fn); }, reorder: function(mapping) { this.suspendEvents(); var items = this.items, index = 0, length = items.length, order = [], remaining = []; //object of {oldPosition: newPosition} reversed to {newPosition: oldPosition} for (oldIndex in mapping) { order[mapping[oldIndex]] = items[oldIndex]; } for (index = 0; index < length; index++) { if (mapping[index] == undefined) { remaining.push(items[index]); } } for (index = 0; index < length; index++) { if (order[index] == undefined) { order[index] = remaining.shift(); } } this.clear(); this.addAll(order); this.resumeEvents(); }, keySort : function(dir, fn){ this._sort('key', dir, fn || function(a, b){ var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase(); return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); }); }, getRange : function(start, end){ var items = this.items; if(items.length < 1){ return []; } start = start || 0; end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1); var i, r = []; if(start <= end){ for(i = start; i <= end; i++) { r[r.length] = items[i]; } }else{ for(i = start; i >= end; i--) { r[r.length] = items[i]; } } return r; }, filter : function(property, value, anyMatch, caseSensitive){ if(!value){ return this.clone(); } value = this.createValueMatcher(value, anyMatch, caseSensitive); return this.filterBy(function(o){ return o && value.test(o[property]); }); }, filterBy : function(fn, scope){ var r = new $.Collection(); r.getKey = this.getKey; var k = this.keys, it = this.items; for(var i = 0, len = it.length; i < len; i++){ if(fn.call(scope||this, it[i], k[i])){ r.add(k[i], it[i]); } } return r; }, findIndex : function(property, value, start, anyMatch, caseSensitive){ if(!value){ return -1; } value = this.createValueMatcher(value, anyMatch, caseSensitive); return this.findIndexBy(function(o){ return o && value.test(o[property]); }, null, start); }, findIndexBy : function(fn, scope, start){ var k = this.keys, it = this.items; for(var i = (start||0), len = it.length; i < len; i++){ if(fn.call(scope||this, it[i], k[i])){ return i; } } return -1; }, createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) { if (!value.exec) { // not a regex value = String(value); if (anyMatch === true) { value = escapeRe(value); } else { value = '^' + escapeRe(value); if (exactMatch === true) { value += '$'; } } value = new RegExp(value, caseSensitive ? '' : 'i'); } return value; }, clone : function(){ var r = new $.Collection(); var k = this.keys, it = this.items; for(var i = 0, len = it.length; i < len; i++){ r.add(k[i], it[i]); } r.getKey = this.getKey; return r; } }; /* * 扩展常用方法 * isArray|isPlainObject|isEmptyObject,三个方法zepto已经存在 */ $.extend($,{ noop:function(){}, error:function( msg ) { throw msg; }, isNumber:function(value) { return typeof value === 'number' && isFinite(value); }, isNumeric: function(value) { return !isNaN(parseFloat(value)) && isFinite(value); }, isString: function(value) { return typeof value === 'string'; }, isBoolean: function(value) { return typeof value === 'boolean'; }, isFunction:function(obj){ return toString.call(obj) === "[object Function]"; }, /*isArray:function(obj) { return toString.call(obj) === "[object Array]"; },*/ //判断是否为object类型的对象 isObject:function(obj){ return toString.call(obj) === "[object Object]"; }, //判断是否为JSON对象,而不是function的实例 /*isPlainObject:function(obj){ //先对数据类型进行判断,并排除DOM类型的对象 if (!obj || toString.call(obj)!=="[object Object]" || obj.nodeType || obj.setInterval){ return false; } //如果有构造方法的属性,那么则是function的实例 if (obj.constructor && !hasOwnProperty.call(obj, "constructor") && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) { return false; } //判断最后一个属性是否是OwnProperty,而不是prototype里的属性 var key; for(key in obj){} //返回判断结果 return key === undefined || hasOwnProperty.call(obj, key); },*/ //判断是否为没有任何属性的对象 isEmptyObject:function(obj){ for (var name in obj) { return false; } return true; }, isElement: function(value) { return value ? value.nodeType !== undefined : false; }, isNodeName:function(elem,name){ return $.nodeName(elem,name); }, //判定nodeName nodeName:function(elem, name){ return elem.nodeName && elem.nodeName.toUpperCase()=== name.toUpperCase(); }, isWindow: function( obj ) { return obj && typeof obj === "object" && "setInterval" in obj; }, trim: function(text) { return (text || "").replace(rtrim,""); }, //判断item是否在数组array中 inArray: function(item, array){ if(array.indexOf){ return array.indexOf(item); } //遍历array进行判定 for(var i=0,length=array.length;i1 && (typeof(r)=="undefined" || r==null)) return arguments[1]; return r; }, parseString:function(str){ str=$.parseJsonString(str); (new Function("this.parseObject(" +str+")")).apply(this); //if(typeof(o)=="object")this.parseObject(o); }, parseObject:function(obj){ for(var p in obj){ if(obj[p] && $.isArray(obj[p])){ this.add(p,new $.DatasetList(obj[p])); }else if(obj[p] && $.isObject(obj[p])){ this.add(p,new $.DataMap(obj[p])); }else{ this.add(p,(obj[p]==undefined || obj[p]==null)?"":obj[p]); } } } }); $.DataMap.prototype.toString=function(){ var cl=[],is=""; for(var key in this.map){ is="\"" + key + "\":"; if(typeof(this.map[key])=="undefined" || this.map[key]==null){ is+="\"\""; }else if(typeof(this.map[key])=="string" || !isNaN(this.map[key])){ is+="\"" + $.parseJsonValue("" + this.map[key]) + "\""; }else{ is+=this.map[key].toString(); } cl.push(is); } return "{" + cl.join(",") + "}"; }; $.DataMap.prototype.put=$.DataMap.prototype.add; $.DatasetList=function(o){ //支持不使用new来构造 if(!this.parseString) { return new $.DatasetList(o); } this.items = []; this.length=0; if(typeof(o)=="string" && o!="")this.parseString(o); if(typeof(o)=="object" && (o instanceof Array) && o.length)this.parseArray(o); }; $.extend($.DatasetList.prototype,{ add:function(o){ this.length=(this.length+1); this.items.push(o); }, item:function(index,key,defaultValue){ if(index < this.length && index >= 0){ var r= this.items[index]; if((typeof(r)!="undefined") && (r instanceof $.DataMap) && arguments.length>1 && typeof(arguments[1])=="string" && arguments[1]!="" ){return r.get(key,defaultValue);} return r; }return; }, each:function(fn, scope){ var items = [].concat(this.items); for(var i = 0, len = items.length; i < len; i=i+1){ if(fn.call(scope || items[i], items[i], i, len) === false){ break; } } }, remove:function(o){ return this.removeAt(this.indexOf(o)); }, removeAt:function(index){ if(index < this.length && index >= 0){ this.length=(this.length-1); this.items.splice(index, 1); } }, indexOf:function(o){ if(!this.items.indexOf){ for(var i = 0, len = this.items.length; i < len; i=i+1){ if(this.items[i] == o){ return i;} } return -1; }else{ return this.items.indexOf(o); } }, getCount:function(){ return this.length; }, parseString:function(str){ str=$.parseJsonString(str); (new Function("this.parseArray(" +str+")")).apply(this); }, parseArray:function(o){ for(var i=0;i 0){ setTimeout(function(){ //检查请求是否正常 if (xhr && !requestDone) { onreadystatechange("timeout"); } }, s.timeout); } //发送data try { xhr.send(type === "POST" || type === "PUT" || type === "DELETE"?s.data:null); } catch(e) { $.handleError(s, xhr, null, e); // 执行complete回调 complete(); } //firefox 1.5不能在异步的XHR请求中触发statechagne事件 if (!s.async) { onreadystatechange(); } function success(){ //执行success回调 if(s.success){ s.success.call(callbackContext, data, status, xhr); } /*if(s.global){ trigger("ajaxSuccess", [xhr, s]); }*/ } function complete(){ //执行complete回调 if (s.complete){ s.complete.call( callbackContext, xhr, status); } //请求完成 /*if (s.global){ //执行全局或context上绑定的ajaxComplete事件 trigger("ajaxComplete", [xhr, s]); }*/ //进行ajax请求计数处理 /*if (s.global && !--$.active){ //执行全局ajaxStop事件 $.event.trigger("ajaxStop"); }*/ } /*function trigger(type, args) { (s.context ? $(s.context) : $.event).trigger(type, args); }*/ //将XMLHttpRequest对象返回,以在必须时可以取消这个XHR请求 return xhr; }, handleError: function(s, xhr, status, e){ //处理error回调 if(s.error){ s.error.call( s.context || s, xhr, status, e ); } //执行全局回调 /*if (s.global){ //触发s.content或全局的ajaxError事件 (s.context ? $(s.context) : $.event).trigger("ajaxError",[xhr, s, e]); }*/ }, //检查XMLHttpRequest请求是否成功 httpSuccess: function(xhr){ try { // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450 return !xhr.status && location.protocol === "file:" || //当其它浏览器中status是304时候,Opera则是0 (xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0; } catch(e) {} return false; }, //通过响应的ResponseHeader内容检查XMLHttpRequest响应是否有更改 httpNotModified: function( xhr, url ) { var lastModified = xhr.getResponseHeader("Last-Modified"), etag = xhr.getResponseHeader("Etag"); if (lastModified) { $.lastModified[url]= lastModified; } if (etag){ $.etag[url] = etag; } //当其它浏览器中status是304时候,Opera则是0 return xhr.status === 304 || xhr.status === 0; }, httpData: function(xhr, type, s){ var ct = xhr.getResponseHeader("content-type") || "", xml = type === "xml" || !type && ct.indexOf("xml") >= 0, data = xml ? xhr.responseXML : xhr.responseText; if(xml && data.documentElement.nodeName === "parsererror"){ $.error("parsererror"); } //如果ajax调用参数中有dataFilter函数,则使用dataFilter函数对返回的数据进行处理 if(s && s.dataFilter){ data = s.dataFilter(data, type); } //解析服务器返回的string数据 if (typeof data === "string"){ //如果请求的数据类型是json,则解析json数据 if (type === "json" || !type && ct.indexOf("json") >= 0){ data = $.parseJSON(data); // 如果请求的数据类型是script,那么执行script }else if( type === "script" || !type && ct.indexOf("javascript") >= 0 ) { $.globalEval(data); } } return data; } }); return $; })(window.Zepto);