原创作者: zdz8207   阅读:5642次   评论:2条   更新时间:2011-05-26    

发布一个最新版coos核心代码

完整版本请到google code开源项目上下载

google.code网址:http://code.google.com/p/coos/

 

coos.js

 

/**
 * @author zdz8207
 * 通用面向对象脚本库
 * @version 0.2
 * 
 */
var coos = function(){this.version = "0.2";};

/**
 * 创建对象和方法的通用函数,兼容多种浏览器,实现高效、方便的继承体系,解决多种常规创建的性能问题
 * @param parantObj jsonObj
 * @example 
 * var Person = coos.Class      //默认派生自object基本类
({
    Create: function(name, age)
    {
        this.base();    //调用上层构造函数
        this.name = name;
        this.age = age;
    },
    SayHello: function()
    {
        alert("Hello, I'm " + this.name + ", " + this.age + " years old.");
    },
    toString: function()    //覆写toString方法
    {
        return this.name;
    }
});

var Employee = coos.Class(Person,    //派生自Person类
{
    Create: function(name, age, salary)
    {
        this.base(name, age);  //调用基类的构造函数
        this.salary = salary;
    },
    ShowMeTheMoney: function()
    {
        alert(this + " $" + this.salary); //这里直接引用this将隐式调用toString()
    }
});
var BillGates = new Person("Bill Gates", 53);
var SteveJobs = new Employee("Steve Jobs", 53, 1234);
alert(BillGates);   //这里将隐式调用覆写后的toString()方法
BillGates.SayHello();
SteveJobs.SayHello();
SteveJobs.ShowMeTheMoney();

var LittleBill = new BillGates.Type("Little Bill", 6); //用BillGate的类型建LittleBill
LittleBill.SayHello();

alert(BillGates.isA(Person));       //true
alert(BillGates.isA(Employee));     //false
alert(SteveJobs.isA(Person));       //true
* 
 */
coos.Class = function()
{
    var aDefine = arguments[arguments.length-1]; //最后一个参数是类定义
    if(!aDefine) return;
    var aBase = arguments.length>1 ? arguments[0] : coos.object; //解析基类
    
    function prototype_(){}; //构造prototype的临时函数,用于挂接原型链
    prototype_.prototype = aBase.prototype;  //准备传递prototype
    var aPrototype = new prototype_();    //建立类要用的prototype
    
    for(var member in aDefine)  //复制类定义到当前类的prototype
    {
        if(member!="Create")    //构造函数不用复制
        {
            aPrototype[member] = aDefine[member];
        }
    }
    //根据是否继承特殊属性和性能情况,可分别注释掉下列的语句
    if(aDefine.toString != Object.prototype.toString)
    {
        aPrototype.toString = aDefine.toString;
    }
    if(aDefine.toLocaleString != Object.prototype.toLocaleString)
    {
        aPrototype.toLocaleString = aDefine.toLocaleString;
    }
    if(aDefine.valueOf != Object.prototype.valueOf)
    {
        aPrototype.valueOf = aDefine.valueOf;
    }
    if(aDefine.Create)  //若有构造函数
    {
        var aType = aDefine.Create;  //类型即为该构造函数
    }
    else    //否则为默认构造函数
	{
        aType = function()
        {
            this.base.apply(this, arguments);   //调用基类构造函数
        };
	}

    aType.prototype = aPrototype;   //设置类(构造函数)的prototype
    aType.Base = aBase;             //设置类型关系,便于追溯继承关系
    aType.prototype.Type = aType;   //为本类对象扩展一个Type属性
    return aType;   //返回构造函数作为类
};

//根类object定义:
coos.object = function(){};    //定义小写的object根类,用于实现最基础的方法等
coos.object.prototype.isA = function(aType)   //判断对象是否属于某类型
{
    var self = this.Type;
    while(self)
    {
        if(self == aType) return true;
        self = self.Base;
    }
    return false;
};

coos.object.prototype.base = function()  //调用基类构造函数
{
    var Base = this.Type.Base;  //获取当前对象的基类  
    if(!Base.Base)  //若基类已没有基类
    {
        Base.apply(this, arguments);     //则直接调用基类构造函数
    }
    else    //若基类还有基类         
    {
        this.base = MakeBase(Base);     //先覆写this.base
        Base.apply(this, arguments);    //再调用基类构造函数
        delete this.base;               //删除覆写的base属性
    }
    function MakeBase(Type) //包装基类构造函数
    {
        var Base = Type.Base;
        if(!Base.Base) return Base; //基类已无基类,就无需包装
        return function()   //包装为引用临时变量Base的闭包函数
        {
            this.base = MakeBase(Base);     //先覆写this.base
            Base.apply(this, arguments);    //再调用基类构造函数
        }
    }
};
/**
 * 扩展函数功能
 * @param destination 要扩展的函数
 * @param source 扩展函数
 * @example
 coos.extend(Array.prototype,{
	clear : function () 
	{
		this.length = 0;
		return this;
	},
	first : function () 
	{
		return this[0];
	},
	last : function () 
	{
		return this[this.length - 1];
	}
});
 */
coos.extend = function(destination, source) {
  for (var property in source)
  {
    destination[property] = source[property];
  }
  return destination;
};

/**
 * simple inherit whit call parent this attribute
 * @param parentFunction
 */
coos.call = function(parentFunction)
{
	var parentfn = parentFunction + ".call(this)";
	eval(parentfn);
};

/**
 * override method
 * @param origclass, overrides the overrides is a json or hashmap
 */
coos.override = function(origclass, overrides)
{
    if(overrides)
    {
        var p = origclass.prototype;
        for(var method in overrides)
        {
            p[method] = overrides[method];
        }
    }
};

/**
 * 克隆对象
 */
coos.clone = function(obj)
{
	var temp = null;
	for(var p in obj)
	{
		temp[p] = obj[p];
	}
	return temp;
};

/**
 * 通用接口函数,为实现设计模式提供支持
 * @param name String类型 接口名称
 * @param methods 字符串数组,每个字符串都是一个必须的方法名称
 * @example 
 	//test coos.Interface 
	var testInterface = new coos.Interface("testInterface",["getId","getName"]);
	
	function adminUser(user)
	{
		//传入的user对象必须实现testInterface的方法
		coos.Interface.impl(user,testInterface);
		//由上面的接口保证了user对象实现了接口方法可以安全使用
		var id = user.getId();
		var name = user.getName();
		var message = "I'm a admin user";
		alert("id = " + id + " name = " + name + " message = " + message);
	}
	
	function vipUser(user)
	{
		//传入的user对象必须实现testInterface的方法
		coos.Interface.impl(user,testInterface);
		//由上面的接口保证了user对象实现了接口方法可以安全使用
		var id = user.getId();
		var name = user.getName();
		var message = "I'm a vip user";
		alert("id = " + id + " name = " + name + " message = " + message);
	}
	
	function user(id,name)
	{
		this.getId = function(){return id};
		this.getName = function(){return name};
	}
	
	adminUser(new user("1","admin"));
	vipUser(new user("2","zdz"));
 * 
 */
coos.Interface = function(name, methods) {
    if(arguments.length != 2) {
        throw new Error("Interface constructor called with " + arguments.length + "arguments, but expected exactly 2.");
    }
    
    this.name = name;
    this.methods = [];
    for(var i = 0, len = methods.length; i < len; i++) {
        if(typeof methods[i] !== 'string')
        {
            throw new Error("Interface constructor expects method names to be " + "passed in as a string.");
        }
        this.methods.push(methods[i]);        
    }    
};

/**
 * 最少传入两个参数,一个为对象,另外为要实现的接口,可传入多个接口
 * 在使用接口方法前作判断coos.Interface.impl(user,testInterface);
 */
coos.Interface.impl = function(object) {
    if(arguments.length < 2) {
        throw new Error("Function Interface.impl called with " + 
          arguments.length  + "arguments, but expected at least 2.");
    }

    for(var i = 1, len = arguments.length; i < len; i++) 
    {
        var _interface = arguments[i];
        if(_interface.constructor !== coos.Interface)
        {
            throw new Error("Function Interface.impl expects arguments "   
              + "two and above to be instances of Interface.");
        }
        
        for(var j = 0, methodsLen = _interface.methods.length; j < methodsLen; j++)
        {
            var method = _interface.methods[j];
            if(!object[method] || typeof object[method] !== 'function')
            {
                throw new Error("Function Interface.impl: object " 
                  + "does not implement the " + _interface.name 
                  + " interface. Method " + method + " was not found.");
            }
        }
    } 
};

/**
 * 反射机制的简单实现
 * @param obj 传入对象为obj类型,可以是json形式的
 * 
 */
coos.reflection = function(obj)
{
	for(var p in obj)
	{
		if(typeof(obj[p]) == "function")
		{
			//如果属性为function类型则执行
			obj[p]();
		}
	}
};

/**
 * 利用闭包构造一个单例类型返回,不能创建新的实例
 * @param fn 闭包函数function(){}的形式
 * @param singletonName 创建的单例类型名称
 * @example
	 var sessionFactory = new coos.singleton(
		function(){
			this.message = "I'm a sessionFactory!";
			this.sayHello = function(){alert("Hello!");}
		},"sessionFactory"
	);
	var mySession = sessionFactory.getInstance();
	mySession.sayHello();
	var newSession = new sessionFactory();// throw 单例类型sessionFactory不能实例化!
 */
coos.singleton = function(fn,singletonName)
{
	singletonName = singletonName || "singletonClass";
	var obj = new fn();
	var singletonClass = function()
	{
		throw new Error("单例类型" + singletonName + "不能实例化!");
	};
	singletonClass.getInstance = function(){return obj;};
	singletonClass.name = singletonName;
	return singletonClass;
};

/**
 * 定义通用的简单命令模式接口
 */
coos.command = new coos.Interface("coos.command",["execute"]);

/**
 * 定义通用的带取消操作的命令模式接口
 */
coos.undocommand = new coos.Interface("coos.undocommand",["execute","undo"]);

/**
 * aop 的实现
 * @param object 必须为对象,不能是方法本身
 * @example
 function aopTest()
{
    this.say1 =  function(s)
	{
        alert(s);
    };
    this.say2 =  function(s)
	{
        alert(s);
    };  
}
   
function beforeHander()
{
    alert("aspect said:");
}
function afterHander()
{
	alert("said by aspect");
}
  

var test = new aopTest();
actsAsAspect(test);
test.before("say1",beforeHander); 
test.after("say1",afterHander);
test.say1("hello I'm say1");

test.before("say2",beforeHander);
test.after("say2",afterHander);
test.say2("hello I'm say2");
 */
coos.aop = function(object)
{
	if(typeof(object) != "object")
	{
		throw new Error("传入的对象类型必须为object!");
		return false;
	}
	object.yield = null;
	object.rv = {};
	object.before  = function(method, f)
	{
		var original = eval("this." + method);
		this[method] = function()
		{
		  f.apply(this, arguments);
		  return original.apply(this, arguments);
		};
	};   
	object.after = function(method, f)
	{
	    var original = eval("this." + method);
	    this[method] = function()
	    {
	      this.rv[method] = original.apply(this, arguments);
	      return f.apply(this, arguments);
	    };
	};   
	object.around = function(method, f)
	{
    	var original = eval("this." + method);
    	this[method] = function()
	    {
	      this.yield = original;
	      return f.apply(this, arguments);
	    };
	};
};

/**
 * 采用prototype的Object扩展方法
 * @param obj 需要判断的对象
 */
coos.extend(Object, {
	extend : function(destination, source) {
	  for (var property in source)
	    destination[property] = source[property];
	  return destination;
	},
	toJSON: function(object) {
    var type = typeof object;
    switch (type) {
      case 'undefined':
      case 'function':
      case 'unknown': return;
      case 'boolean': return object.toString();
    }

    if (object === null) return 'null';
    if (object.toJSON) return object.toJSON();
    if (Object.isElement(object)) return;

    var results = [];
    for (var property in object) {
      var value = Object.toJSON(object[property]);
      if (!Object.isUndefined(value))
        results.push(property.toJSON() + ': ' + value);
    }
    return '{' + results.join(', ') + '}';
  },
  keys: function(object) {
    var keys = [];
    for (var property in object)
      keys.push(property);
    return keys;
  },
  values: function(object) {
    var values = [];
    for (var property in object)
      values.push(object[property]);
    return values;
  },
  clone: function(object) {
    return Object.extend({ }, object);
  },
  isElement: function(object) {
    return object && object.nodeType == 1;
  },
  isArray: function(object) {
  	//判断是否为数组,考虑到多种情况
  	return Object.prototype.toString.call(object) === '[object Array]';
    //return object != null && typeof object == "object" && 'splice' in object && 'join' in object;
  },
  isHash: function(object) {
    return object instanceof Hash;
  },
  isFunction: function(object) {
    return typeof object == "function";
  },
  isString: function(object) {
    return typeof object == "string";
  },
  isNumber: function(object) {
    return typeof object == "number";
  },
  isUndefined: function(object) {
    return typeof object == "undefined";
  }
});

/**
 * json的处理函数
 * parse函数把json字符串转换成对象
 * toJSONString把对象转换成json字符串(包括普通对象和json对象)
 */
coos.json = {
	parse : function(data)
	{
		if(typeof(data) != "object")
		{
			data = eval('(' + data + ')');
		}
		return data;
	},
	toJSONString : function(obj)
	{
		switch(typeof(obj))
		{
			case "object" :
			{
				var result = [];
				if(obj instanceof Array)
				{
					var len = obj.length;
					for(var i = 0; i < len; i++)
					{
						result.push(coos.json.toJSONString(obj[i]));
					}
					return "[" + result.toString(",") + "]";
				}
				else if(obj instanceof RegExp)
				{
					return obj.toString();
				}
				else
				{
					for(var attribute in obj)
					{
						result.push(attribute + ":" + coos.json.toJSONString(obj[attribute]));
					}
					return "{" + result.join(",") + "}";
				}
			}
			case "function":
			{
				return "function(){}";
			}
			case "number":
			{
				return obj.toString();
			}
			case "boolean":
			{
				return obj.toString();
			}
			case "string":
			{
				return "\"" + obj.replace(/(\\|\")/g, "\\$1").replace(/\n|\r|\t/g,function(a){return ("\n" == a) ? "\\n":("\r" == a) ? "\\r":("\t" == a) ? "\\t":"";}) + "\"";
			}
			default:
			{
				return obj.toString();
			}
		}
	}
};

/**
 * 引入script和css文件
 */
coos.include = function()
{
	function create(src)
	{
		var sobj = document.createElement('script'); 
		sobj.type = "text/javascript"; 
		sobj.src = src; 
		document.getElementsByTagName('head')[0].appendChild(sobj);
	}
	
	function getScriptPath(key)
	{
		var scripts = document.getElementsByTagName("script");
		var len = scripts.length;
		for (var i = 0; i < len; i++)
		{
			if(scripts[i].src.indexOf(key) != -1)
				return scripts[i].src.split(key)[0];
		}
		return null;
	}
	//获得script的路径,只传入文件名则默认为coos.js同一个目录
	function path(src,key)
	{
		if(src.indexOf("/") != -1)
		{
			return src;
		}
		else
		{
			var key = key || "coos.js";
			return getScriptPath(key) + src;
		}
	}
	
	return{
		script : function()
		{
			var len = arguments.length;
			
			for(var i = 0; i < len; i++)
			{
				create(path(arguments[i]));
			}
		},
		css : function()
		{
			var len = arguments.length;
			
			for(var i = 0; i < len; i++)
			{
				var css = document.createElement("link");
				css.rel = "stylesheet";
				css.type = "text/css";
				css.href = path; 
				create(css);
			}
		}
	}
	
}();


/**
 * browser userAgent
 */
coos.userAgent = navigator.userAgent.toLowerCase();
/**
 * Figure out what browser is being used 
 */
coos.browser = {
	version: (coos.userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
	safari: /webkit/.test(coos.userAgent),
	opera: /opera/.test(coos.userAgent),
	msie: /msie/.test(coos.userAgent) && !/opera/.test(coos.userAgent),
	mozilla: /mozilla/.test(coos.userAgent) && !/(compatible|webkit)/.test(coos.userAgent)
};

/**
 * 简单的兼容浏览器的onload事件绑定
 * @param fn 需要绑定window.onload后执行的function
 */
coos.onloadEvent = function(fn)
{
	if (window.attachEvent) 
	{
		window.attachEvent("onload", fn);
	}
	else
	{
		window.addEventListener("load",fn,false);
	}
};

//由于导入文件太多可能导致难以预料的问题,把主要函数开发稳定后合并在同类脚本里面可以减少不必要的异常
coos.include.script("coos.extbase.js");
coos.include.script("coos.ui.js");
//由于ajax文件内容比较多,还不稳定故单独导入
coos.include.script("coos.extend.ajax.js");


 

 

coos.ext.base.js

/**
 * String extend
 */
coos.extend(String.prototype,{
	trim : function () 
	{
	    return this.replace(/(^\s*)|(\s*$)/g, "");
	},
	ltrim : function () 
	{
	    return this.replace(/^\s*/g, "");
	},
	rtrim : function ()
	{
	    return this.replace(/\s*$/g, "");
	},
	Trim : function() 
	{ 
	    return this.replace(/(^\s*)|(\s*$)/g, ""); 
	},
	LTrim : function() 
	{ 
	    return this.replace(/(^\s*)/g, ""); 
	},
	Rtrim : function() 
	{ 
	    return this.replace(/(\s*$)/g, ""); 
	},
	contains : function (string, s) 
	{
	    return (s) ? (s + this + s).indexOf(s + string + s) > -1 : this.indexOf(string) > -1;
	},
	equals : function () 
	{
	    for (var i = 0; i < arguments.length; i++) 
		{
	        if (this == arguments[i])
	            return true;
	    }
	    return false;
	},
	startsWith : function (A) 
	{
	    return (this.substr(0, A.length) == A);
	},
	endsWith : function (A, B) 
	{
	    var C = this.length;
	    var D = A.length;
	    if (D > C) 
		{
	        return false;
	    }
	    if (B) 
		{
	        var E = new RegExp(A + "$", "i");
	        return E.test(this);
	    } 
		else
		{
	        return (D == 0 || this.substr(C - D, D) == A);
	    }
	},
	remove : function (A, B)
	{
	    var s = "";
	    if (A > 0) {
	        s = this.substring(0, A);
	    }
	    if (A + B < this.length)
		{
	        s += this.substring(A + B, this.length);
	    }
	    return s;
	},
	replaceNewLineChars : function (A) 
	{
	    return this.replace(/\n/g, A);
	},
	escape : function () 
	{
		return this.replace(/('|\\)/g, "\\$1");
	},
	intercept : function(len)
	{
		if(this.length*2 <= len)
			return this;
		var strlen = 0; 
		var s = "";
		for(var i = 0; i < this.length; i++)
		{
			if(this.charCodeAt(i) > 128)
			{			
				strlen = strlen + 2;
				if(strlen > len)
					return s.substring(0,s.length-1) + "...";
			}
			else
			{
				strlen = strlen + 1;
				if(strlen > len)
					return s.substring(0,s.length-2) + "...";
			}
			s = s + this.charAt(i);
		}
		return s;
	},
	getFileType : function()
	{
		return this.substring(this.lastIndexOf(".")+1,this.length).toLowerCase();
	},
	toInt : function()
	{
		return parseInt(this, 10);
	},
	toFloat : function()
	{
		return parseFloat(this);
	},
	toArray : function(sp)
	{
		if(sp)
		{
			return this.trim().split(sp);
		}
		var arr = new Array();
		for(var i = 0; i < this.length; i++)
		{
			arr[i] = this.substr(i,1);
		}
		return arr;
	},
	random : function()
	{
		var arr = this.toArray();
		return arr[Math.floor(Math.random() * arr.length)] || null;
	},
	clean : function()
	{
		return this.replace(/\s{2,}/g, ' ').trim();
	},
	toJson : function()
	{
		return eval('(' + this + ')');
	}
});


function StringBuffer()
{
	var arr = new Array;
	return{
		append : function(str)
		{
			arr[arr.length] = str;  
		},
		toString : function()
		{
			return arr.join(""); 
		}
	};
}

/**
 * Arrary extend
*/
coos.extend(Array.prototype,{
	clear : function () 
	{
		this.length = 0;
		return this;
	},
	first : function () 
	{
		return this[0];
	},
	last : function () 
	{
		return this[this.length - 1];
	},
	size : function () 
	{
		return this.length;
	},
	contains : function (value) 
	{
		for(var i in this)
		{
			if(this[i] == value)  return true;
		}
		return false;
	},
	append : function(value) 
	{
		this.push(value);
		return this;
	},
	remove: function(value) 
	{
		for(var i in this)
		{
			if(this[i] == value)
			{
				this.splice(i,1);
			}
		}
		return this;
	},
	random : function(min, max)
	{
		if(min && max)
		{
			return this[Math.floor(Math.random() * (max - min + 1) + min)] || null;
		}
		else
		{
			return this[Math.floor(Math.random() * this.length)] || null;
		}
	},
	copy : function(value) 
	{
	    var temp = [];
		for(var i in this)
		{
			temp[i] = this[i];
		}
		return temp;
	},
	compare : function(arr)
	{
		for(var i in arr)
		{
			if(!this.contains(arr[i])) return false;
		}
		for(var j in this)
		{
			if(!arr.contains(this[j])) return false;
		}
		return true;
	},
	indexOf : function(item, from)
	{
		var len = this.length;
		for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++)
		{
			if (this[i] === item) 
			{
				return i;
			}
		}
		return -1;
	},
	lastIndexOf : function (item, from) 
	{
		var len = this.length;
		for (var i = (from < len) ? Math.max(0, len - from) : len || 0; i > -1; i--)
		{
			if (this[i] === item) 
			{
				return i;
			}
		}
		return -1;
	},
	count : function () 
	{
		var count = this.length;
		var len = this.length;
		for(var i = 0; i < len; i++)
		{
			for(var j = i+1; j < len; j++)
			{
				if(this[i] == this[j]) count--;
			}
		}
		return count;
	},
	isSingle : function(arr)
	{
		var len = arr.length;
		for(var i = 0; i < len; i++)
		{
			for(var j = i+1; j < len; j++)
			{
				if(arr[i] == arr[j]) return false;
			}
		}
		return true;
	},
	sum : function() 
	{
	    var temp = 0;
		for(var i in this)
		{
			if(!isNaN(this[i]))
				temp += this[i];
		}
		return temp;
	},
	include : function(arr)
	{
		for(var i in arr)
		{
			if(!this.contains(arr[i])) return false;
		}
		return true;
	},
	innercount : function(arr)
	{
		var count = 0;
		for(var i in arr)
		{
			if(this.contains(arr[i])) count++;
		}
		return count;
	},
	outcount : function(arr)
	{
		var count = 0;
		for(var i in arr)
		{
			if(arr.contains(this[i])) count++;
		}
		return count;
	},
	/**
	 * function printElt(element, index, array) {
	    print("[" + index + "] is " + element); // assumes print is already defined
	}
	[2, 5, 9].forEach(printElt);
	// Prints:
	// [0] is 2
	// [1] is 5
	// [2] is 9
	 */
	forEach : function(fn, bind)
	{
		for (var i = 0, j = this.length; i < j; i++) fn.call(bind, this[i], i, this);
	},
	each : function(iterator) 
	{
	    for (var i = 0, length = this.length; i < length; i++)
	    {
	    	if(typeof this[i] != "function")
	      		iterator(this[i]);
	      	else
	      		this[i].call(this);
	    }
	},
	every : function(fn, bind)
	{
		for (var i = 0, j = this.length; i < j; i++){
			if (!fn.call(bind, this[i], i, this)) return false;
		}
		return true;
	},
	some : function(fn, bind)
	{
		for (var i = 0, j = this.length; i < j; i++){
			if (fn.call(bind, this[i], i, this)) return true;
		}
		return false;
	},
	map : function(fn, bind)
	{
		var results = [];
		for (var i = 0, j = this.length; i < j; i++) results[i] = fn.call(bind, this[i], i, this);
		return results;
	},
	filter : function(fn, bind)
	{
		var results = [];
		for (var i = 0, j = this.length; i < j; i++){
			if (fn.call(bind, this[i], i, this)) results.push(this[i]);
		}
		return results;
	},
	toArray : function(index)
	{
		var results = [];
		for (var i = index, j = this.length; i < j; i++){
			results.push(this[i]);
		}
		return results; 
	},
	toString : function(sp)
	{
		var temp = sp || "";
		return this.join(temp); 
	},
	end : {}
	
});

/**
 * hashmap extend
 */
coos.hashmap = function()
{
	function hash(_key, _value)
	{
		this.key	= _key;
		this.value	= _value;
	};
	var map = new Array();
	
	return {
		set : function(key,value)
		{
			for (var i = 0; i < map.length; i++)
			{
				if (map[i].key == key )
				{
					map[i].value = value;
					return;
				}
			}
			map[map.length] = new hash(key,value);			
		},
		get : function(key)
		{
			for (var i = 0; i < map.length; i++)
			{
				if (map[i].key == key)
					return map[i].value;
			}
			return null;
		},
		size : function()
		{
			return map.length;
		},
		getKey : function(index)
		{
			if (map.length <= index)
				return null;
			return map[index].key;
		},
		getValue : function(index)
		{
			if (map.length <= index)
				return null;
			return map[index].value;
		},
		getLastKey : function()
		{
			return map[map.length-1].key;
		},
		getLastValue : function()
		{
			return map[map.length-1].value;
		},
		getKeys : function()
		{
			var keys = [];
			map.forEach(function(_hash){
				keys.push(_hash.key);
			});
			return keys;
		},
		getValues : function()
		{
			var values = [];
			map.forEach(function(_hash){
				values.push(_hash.value);
			});
			return values;
		},
		toString : function()
		{
			var arr = [];
			map.forEach(function(_hash){
				arr.push("\"" + _hash.key + "\":\"" + _hash.value + "\"");
			});
			return "{" + arr.toString(",") + "}";
		},
		toJson : function()
		{
			return this.toString().toJson();
		},
		remove : function(key)
		{
			for(var i = 0; i < map.length; i++)
			{
				if(map[i].key == key)
					map.splice(i,1);
			}
		},
		isEmpty : function()
		{
			return (map.length == 0);
		},
		sort : function()
		{
			map = map.sort();
		},
		clear : function()
		{
			map = [];
		}
	};
};

/**
 * Event extend
 */
coos.event = function(e)
{
	var e = e || window.event;
	return e;
};

coos.event.format = function(e) 
{
	var e = e || window.event;
	if(!e.pageX || !e.pageY)//firefox3 nonsupport pageX
	{
		e.pageX = e.clientX + document.body.scrollLeft;
		e.pageY = e.clientY + document.documentElement.scrollTop;
	}
	if(window.event)
	{
		e.charCode = (e.type == "keypress") ? e.keyCode : 0;
		e.eventPhase = 2;
		e.isChar = (e.charCode > 0);
		e.preventDefault = function ()
		{
			this.returnValue = false;
		};
		
		if(e.type == "mouseout")
		{
			e.relatedTarget = e.toElement;
		}
		else if(e.type == "mouseover")
		{
			e.relatedTarget = e.formElement;
		}
		
		e.stopPropagation = function ()
		{
			this.cancelBubble = true;
		};
		
		e.target = e.srcElement;
		e.time   = (new Date()).getTime();
	}
	
	if (e.target.nodeType == 3)
	{
		e.target = e.target.parentNode;// defeat Safari bug
	}
	//如果不存在keyCode属性,同时存在which属性则赋值,因为该属性为只读属性
	if(!e.keyCode && e.which)
	{
		e.keyCode = e.which;
	}
	return e;
};

coos.event.add = function(el,EventType,callback)
{
	var obj = coos.$obj(el);
	
	if(obj.addEventListener)
	{
		obj.addEventListener(EventType,callback,false);
	}
	else if(obj.attachEvent)
	{
		obj.attachEvent('on'+EventType,callback);
	} 
	else
	{
		obj['on'+EventType] = callback;
	}
};

coos.event.remove = function(el,EventType,callback)
{
	var obj = coos.$obj(el);
	
	if(obj.removeEventListener)
	{
		obj.removeEventListener(EventType,callback,false);
	} 
	else if(obj.detachEvent)
	{
		obj.detachEvent('on'+EventType,callback);
	} 
	else
	{
		obj['on'+EventType] = callback;
	}
};

coos.event.stop = function(e) 
{
    coos.event.format(e).stopPropagation();
};

coos.event.cancel = function(e) 
{
    coos.event.format(e).preventDefault();
};

coos.event.pageX = function(e)
{
	return coos.event.format(e).pageX;
};

coos.event.pageY = function(e)
{
	return coos.event.format(e).pageY;
};

coos.event.element = function(e)
{
	return coos.event.format(e).target;
};

coos.event.keyCode = function(e)
{
	return coos.event.format(e).keyCode;	
};

 

coos.ui.js

 

/**
 * 根据id快速获取dom对象的方法
 * @param id 字符串类型
 * @return DOM element
 */
coos.$id = function(id)
{
  return document.getElementById(id);
};

/**
 * 根据name快速获取dom对象的方法
 * @param name 字符串类型
 * @return DOM elements
 */
coos.$name = function(name)
{
  return document.getElementsByName(name);
};

/**
 * 在不确定传入id还是obj类型时快速获取dom对象的方法
 * @param el 元素id或对象
 * @return DOM element
 */
coos.$obj = function(el)
{
	var obj = el;
	if(typeof(el) == "string")
		obj = document.getElementById(el);
	return obj;
};

/**
 * 获取元素下面所有传入类型的对象.
 * @param tag 标签名称
 * @param el 元素id或对象,为空或不存在则默认为document
 * @example
 获取id为testTag的div下所有li对象为:coos.$tag("li","testTag");
 获取所有li对象为:coos.$tag("li");
 */
coos.$tag = function(tag,el)
{
	var el = coos.$obj(el) || document;
	return el.getElementsByTagName(tag);
};

/**
 * 获取元素的类型名称(如div span)
 */
coos.$tagName = function(el)
{
	return coos.$obj(el).tagName.toLowerCase();
};

/**
 * 获取iframe的contentWindow对象
 */
coos.$F = function(el)
{
	if(!coos.$obj(el) || coos.$tagName(el) != "iframe")
		return null;
	return coos.$obj(el).contentWindow;
};

/**
 * 取得某个范围内的随机数
 */
coos.$random = function(min, max)
{
	return Math.floor(Math.random() * (max - min + 1) + min);
};

/**
 * 获得当前时间
 */
coos.$time = function()
{
	return new Date().getTime();
};

/**
 * 返回document.body
 */
coos.$body = function()
{
	return document.body;
};

/**
 * 获取元素的innerhtml内容
 * @param el 元素id或对象,默认为document.body
 */
coos.$html = function(el)
{
	var obj = coos.$obj(el)|| document.body;
	return 	obj.textContent || obj.innerText;
};

/**
 * 获取元素的文本内容
 * @param el 元素id或对象
 */
coos.$text = function(el)
{
	var obj = coos.$obj(el);
	return 	obj.textContent || obj.innerText;
};

/**
 * 创建元素
 * coos.$create("div")返回一个未绑定到DOM上的div对象
 */
coos.$create = function(tag)
{
	return document.createElement(tag);
};

/**
 * 添加元素
 * @param el 要添加子元素的父元素
 * @param 要添加的子元素
 */
coos.$append = function(el,child)
{
	coos.$obj(el).appendChild(coos.$obj(child));
};

/**
 * 删除元素对应的class
 */
coos.$removeClass = function(className,el)
{
	coos.$obj(el).className = coos.$obj(el).className.replace(new RegExp("( ?|^)" + className + "\\b"), "");
};

/**]
 * 删除元素下对应标签元素所有对应的样式
 */
coos.$removeTagClass = function(className,tag,el)
{
	var els = coos.$tag(tag,el);
	var len = els.length;
	for(var i = 0; i < len; i++)
	{
		coos.el.removeClass(className,els[i]);
	}
};

/**
 * 因此元素下所有对应标签的元素
 */
coos.$hiddenTag = function(tag,el)
{
	var els = coos.$tag(tag,el);
	var len = els.length;
	for(var i = 0; i < len; i++)
	{
		els[i].style.display = "none";
	}
};

/**
 * 插入html代码,解决火狐下不能直接插入html字符串的问题
 */
coos.$insert = function(where, el, html)
{
	where = where.toLowerCase();   
	if(el.insertAdjacentHTML)
	{
	    switch(where)
	    {   
	        case "before":   
	            el.insertAdjacentHTML('beforeBegin', html);   
	            return el.previousSibling;
	            break;
	        case "top":   
	            el.insertAdjacentHTML('afterBegin', html);   
	            return el.firstChild;
	            break;
	        case "bottom":   
	            el.insertAdjacentHTML('beforeEnd', html);   
	            return el.lastChild;
	            break; 
	        case "after":   
	            el.insertAdjacentHTML('afterEnd', html);   
	            return el.nextSibling;
	            break;
	    }
	    throw 'Illegal insertion point -> "' + where + '"';   
	}
	
	var range = el.ownerDocument.createRange();   
    var frag;
    switch(where)
    {   
         case "before":   
            range.setStartBefore(el);   
            frag = range.createContextualFragment(html);   
            el.parentNode.insertBefore(frag, el);   
            return el.previousSibling;
            break;
         case "top":   
            if(el.firstChild)
            {   
                range.setStartBefore(el.firstChild);   
                frag = range.createContextualFragment(html);   
                el.insertBefore(frag, el.firstChild);   
                return el.firstChild;
            }else
            {   
                el.innerHTML = html;   
                return el.firstChild;   
            }
            break;
        case "bottom":   
            if(el.lastChild)
            {   
                range.setStartAfter(el.lastChild);   
                frag = range.createContextualFragment(html);   
                el.appendChild(frag);   
                return el.lastChild;   
            }
            else
            {   
                el.innerHTML = html;   
                return el.lastChild;   
            }
            break;
        case "after":   
            range.setStartAfter(el);   
            frag = range.createContextualFragment(html);   
            el.parentNode.insertBefore(frag, el.nextSibling);   
            return el.nextSibling; 
            break;  
        }   
        throw 'Illegal insertion point -> "' + where + '"';
};

/**
 * 添加样式
 */
coos.style = {
	add : function(content)
	{
		var style = null;
	    if(document.all)
	    {
	        style = document.createStyleSheet();
	        style.cssText = content;
	    }
	    else
	    {
	        style = document.createElement("style");
	        style.type = "text/css";
	        //style.innerHTML = content;//Safari、Chrome 下innerHTML只读
	        style.textContent = content;
	        try
	        {
	    		document.getElementsByTagName("head")[0].appendChild(style);
	    	}
	    	catch(e){}
	    }
	}
};

/**
 * 提供url常用操作功能
 * random 在url后面加入随机数参数
 * getAttribe 获得url中的参数值
 * replaceAttribe 替换url中的参数值
 * addAttribe 添加参数
 * getAction 获得url中action的名字(后缀可变)
 * location url跳转
 */
coos.url = {
	random : function(url)
	{
		if (url.indexOf ("?") > 0)
		{
			url = url + "&random=" + new Date().getTime();
		}
		else
		{
			url = url + "?random=" + new Date().getTime();
		}
		return url;
	},
	getAttribe : function(type,url)
	{
		var url = url || location.href;
		var urltemp = url.split(type + "=")[1];
		if(!urltemp) return "";
		if(urltemp.indexOf("&") == -1) 
		{
			return urltemp;
		}
		else
		{
			return urltemp.split("&")[0];
		}
	},
	replaceAttribe : function(type,value,url)
	{
		var url = url || location.href;
		
		var oReg = new RegExp(type + "=([^&]+)?","g");
		
		url= url.replace(oReg, type + "=" + value);
		return url;
	},
	addAttribe : function(type,value,url)
	{
		var url = url || location.href;
		if(url.indexOf ("?") == -1)
		{
			return (url + "?" + type + "=" + value);
		}
		else
		{
			return (url + "&" + type + "=" + value);
		}
	},
	getAction : function(url,action)
	{
		var url = url || location.href;
		var action = action || ".action";
		var temp = url.split(action)[0];
		return temp.substring(temp.lastIndexOf("/")+1,temp.length);
	},
	location : function(url,message)
	{
		var url = url || location.href;
		if(!message)
		{
			window.location = url;
			return false; 
		}
		if(confirm(message))
		{
			window.location = url;
		}
		return false; 
	}
};

/**
 * iframe的处理函数
 * 提供批量和单独iframe自适应高度功能
 */
coos.iframe = {
	autoHeights : function(els)
	{
		for (var i = 0; i < arguments.length; i++) 
		{
	        coos.iframe.autoHeight(arguments[i]);
	    }
	},
	autoHeight : function(el)
	{
		var obj = coos.$obj(el);
		var id = obj.id;
		var subWeb = document.frames ? document.frames[id].document : obj.contentDocument;   
		if(obj != null && subWeb != null)
		{
			//iframe body 设置为height:100%;时火狐下最小高度为150
			obj.height = parseInt(subWeb.body.scrollHeight) + "px";
		   
		}
	}
};

coos.form.input = function(){};

coos.form.input.radio = function(name)
{
	var rs = coos.$name(name);
	var len = rs.length;
	for(var i = 0; i < len; i++)
	{
		if(rs[i].checked)
		{
			return rs[i];
		}
	}
	return null;
};

/**
 * form相关的通用函数
 */
coos.form = {
	submit : function(formElement)
	{
		if(!coos.$obj(formElement))return false;
		coos.$obj(formElement).submit();
		return false;
	},
	update : function(formElement,formName,action)
	{
		if(formName)
			formElement.name = formName;
		if(action)
			formElement.action = action;
	},
	validate : function(){}
};

coos.form.checkbox = function(){};

coos.form.checkbox.getElements = function(formElement)
{
	var form = coos.$obj(formElement) || document;
    return form.getElementsByTagName("input"); 
};

coos.form.checkbox.isSelect = function(formElement) 
{
	var els = coos.form.checkbox.getElements(formElement);
    var len = els.length;
    for (var i = 0; i < len; i++)
    {
		if(els[i].checked == true)
		{
       		return true;
		}
    }
    return false;
};

coos.form.checkbox.selectAll = function(formElement) 
{
	var els = coos.form.checkbox.getElements(formElement);
    var len = els.length;
    for (var i = 0; i < len; i++)
    {
		if(els[i].type == "checkbox")
		{
       		els[i].checked = true;
		}
    }
};

coos.form.checkbox.unselectAll = function(formElement) 
{
	var els = coos.form.checkbox.getElements(formElement);
    var len = els.length;
    for (var i = 0; i < len; i++)
    {
		if(els[i].type == "checkbox")
		{
       		els[i].checked = false;
		}
    }
};

coos.form.checkbox.reverse = function(formElement) 
{
	var els = coos.form.checkbox.getElements(formElement);
    var len = els.length;
    for (var i = 0; i < len; i++)
    {
		if(els[i].type == "checkbox")
		{
			els[i].checked = !els[i].checked;
		}
    }
};

coos.form.validate.htmltotext = function(html)
{
	return html.replace(/<[^>]*>/g,"");
};

coos.form.validate.limitlength = function(obj,length)
{
	if(obj.value.length > length)
	{
		obj.value = obj.value.substring(0,length);
		alert("长度不能超过" + length + "个字符!");
	}
};

/**
 * 光标移动到文本域清除默认提示,如果没有输入内容光标离开重新恢复默认提示。
 * onFocus="coos.form.clearDefaultText(this,'我来说两句')",必须用onFocus再重新获得焦点时才起作用
 */
coos.form.clearDefaultText = function(el,message)
{
	var obj = coos.$obj(el);
	if(obj.value == message)
	{
		obj.value = "";
	}
	obj.onblur = function()
	{
		if(obj.value == "")
		{
			obj.value = message;
		}
	}
};

coos.cookie = {
	set : function(name,value,days,path,domain,secure)
	{
		var days = days || 100;
		var path = path || "/";
		var domain = domain || "";
		var secure = secure || "";
	    var exp  = new Date();
	    exp.setTime(exp.getTime() + days*24*60*60*1000);
	    document.cookie = name + "="+ escape (value) 
	    + ";expires=" + exp.toGMTString()
	    + ";path="+ path
	    + (domain == "" ? "" : ("; domain=" + domain))
	    + (secure ? "; secure" : "");
	},
	get : function(name)
	{
		var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
		if(arr != null)
			return unescape(arr[2]);
		return null;
	},
	del : function(name)
	{
		var exp = new Date();
	    exp.setTime(exp.getTime() - 1);
	    var cval=this.get(name);
	    if(cval!=null)
	    	document.cookie= name + "="+cval+";expires="+exp.toGMTString();
	}
};

/**
 * window屏幕宽高和固定位置的相关函数
 */
coos.window = function(){};
coos.window.winWidth  = 0;
coos.window.winHeight = 0;

/**
 * 获取屏幕宽度的函数,在非xhtml标准页面下有可能有问题
 */
coos.window.width = function()
{
	if (window.innerWidth)//for Firefox
	{
		coos.window.winWidth = window.innerWidth;
	}
	else if((document.body) && (document.body.clientWidth))
	{
		coos.window.winWidth = document.body.clientWidth;
	}

	if (document.documentElement && document.documentElement.clientWidth)
	{
		coos.window.winWidth = document.documentElement.clientWidth;
	}
	return coos.window.winWidth;
};

/**
 * 获取屏幕高度的函数
 * html,body高度属性必须设值为height:100%否则在火狐浏览器下获取不到真实高度
 */
coos.window.height = function()
{
	if (window.innerHeight)//for Firefox
	{
		coos.window.winHeight = window.innerHeight;
	}
	else if((document.body) && (document.body.clientHeight))
	{
		coos.window.winHeight = document.body.clientHeight;
	}

	if (document.documentElement  && document.documentElement.clientHeight)
	{
		coos.window.winHeight = document.documentElement.clientHeight;
	}
	return coos.window.winHeight;
};

/**
 * 获取滚动条横向宽度
 */
coos.window.scrollWidth = function()
{
	return document.body.scrollWidth + "px";
};

/**
 * 获取滚动条竖向高度,取body.scrollHeight和documentElement.scrollHeight中最高的一个
 */
coos.window.scrollHeight = function()
{
	return Math.max(document.body.scrollHeight,document.documentElement.scrollHeight) + "px";
};

coos.window.onscroll = function(){};

/**
 * window.onscroll绑定事件
 * @param fn 需要绑定的function
 */
coos.window.onscroll.add = function(fn)
{
	if (window.addEventListener) 
	{
		window.addEventListener("scroll",fn,false);
	}
	else
	{
		window.attachEvent("onscroll", fn);
	}
};

/**
 * 删除window.onscroll绑定事件
 * @param fn 需要绑定的function
 */
coos.window.onscroll.remove = function(fn)
{
	if (window.removeEventListener) 
	{
		window.addEventListener("scroll",fn,false);
	}
	else
	{
		window.detachEvent("onscroll", fn);
	}
};

/**
 * window.onload绑定事件
 * @param fn 需要绑定的function
 */
coos.window.onload = function(fn)
{
	if (window.addEventListener) 
	{
		window.addEventListener("load",fn,false);
	}
	else
	{
		window.attachEvent("onload", fn);
	}
};

/**
 * 让元素显示在屏幕中间,元素必须是绝对定位的
 * @param obj 要显示的对象,改变top left 属性值
 * @param event 触发的事件,在有滚动条的情况下必须传入事件以获取当时所在的滚动条高度
 * @example
<style type="text/css">
		html,body {margin: 0; padding: 0;height:100%;font-size: 14px;}
	  </style>
    <script type="text/javascript">  
	function show(event)
	{
		var obj = document.getElementById("showDiv");
		coos.window.center(obj,event);
		//元素在屏幕中间距离顶部的高度
		var top = coos.window.center.top(obj);
		//固顶在屏幕上,不随滚动条变化
		coos.window.fixed.set(obj,top);
		coos.window.fixed();
	}
    </script>
	<div id="showDiv" style="position:absolute;left:20px;top:5px;height:20px;width:400px;border:2px solid #ccc;text-align: center;clear: both;">
		I'm a div,I can show and fixed in center!
	</div>
	<div style="clear: both;margin:80px;height:1000px;">
		<br /><br />
		<a href="javascript:void(0)" onclick="show(event)">show div center</a>
	</div>
 */
coos.window.center = function(obj,event)
{
	var e = event || window.event;
	if(e)
	{
		obj.style.left = ((coos.window.width() - parseInt(obj.style.width,10))/2).toFixed() + "px";
		var objh = (parseInt(obj.style.height,10)/2).toFixed();
		var sh = parseInt(Math.max(document.body.scrollTop,document.documentElement.scrollTop),10);
		var wh = parseInt((coos.window.height()/2).toFixed(),10);
		var ch = sh + wh;
		obj.style.top  = (ch - objh) + "px";
	}
	else
	{
		obj.style.left = ((coos.window.width() - parseInt(obj.style.width,10))/2).toFixed() + "px";
		obj.style.top  = ((coos.window.height() - parseInt(obj.style.height,10))/2).toFixed() + "px";
	}
};

/**
 * 获取屏幕中间显示距离顶部的高度
 */
coos.window.center.top = function(obj)
{
	return ((coos.window.height() - parseInt(obj.style.height,10))/2).toFixed();
};

/**
 * 固顶元素在屏幕中显示,不随滚动条的变化而变化
 */
coos.window.fixed = function()
{
	coos.window.onscroll.add(coos.window.fixed.bind);
};

/**
 * 绑定需要固顶高度的元素window.onscroll事件
 */
coos.window.fixed.bind = function()
{
	if(!coos.window.fixed.obj || !coos.window.fixed.top)
	{
		return;
	}
	var objs = coos.window.fixed.obj;
	var tops = coos.window.fixed.top;
	var len = objs.length;
	//ie6.0以下不支持position:fixed;属性
	if(coos.browser.msie && parseInt(coos.browser.version) <= 6)
	{
		for(var i = 0; i < len;i++)
		{
			var sh = parseInt(Math.max(document.body.scrollTop,document.documentElement.scrollTop),10);
			objs[i].style.top = (sh + tops[i]) + "px";
		}
	}
	else
	{
		for(var i = 0; i < len;i++)
		{
			objs[i].style.position = "fixed";
			objs[i].style.top = tops[i] + "px";
		}
		//设置完position:fixed;属性和top属性后移除onscroll事件
		coos.window.onscroll.remove(coos.window.fixed.bind);
	}
};

/**
 * 设置需要固定高度的元素
 * @param obj 需要固定高度的元素对象
 * @param top 需要固定高度的元素距离顶部的高度
 */
coos.window.fixed.set = function(obj,top)
{
	if(!coos.window.fixed.obj)
	{
		coos.window.fixed.obj = new Array();
	}
	coos.window.fixed.obj.push(obj);
	
	if(!coos.window.fixed.top)
	{
		coos.window.fixed.top = new Array();
	}
	top = parseInt(top,10);
	coos.window.fixed.top.push(top);
};


 

 

完整版本请到google code开源项目上下载

google.code网址:http://code.google.com/p/coos/

评论 共 2 条 请登录后发表评论
2 楼 路口←↑↓→口 2011-11-22 10:46
  [img][/img]
1 楼 chs112233 2009-10-21 16:33
[flash=200,200][url][img][url][img][list]
[*]
引用
[u][i][b][flash=200,200][/flash][/b][/i][/u]
[/list][/img][/url][/img][/url][/flash]

发表评论

您还没有登录,请您登录后再发表评论

文章信息

  • zdz8207在2009-09-02创建
  • zdz8207在2011-05-26更新
  • 标签: coos javascript
Global site tag (gtag.js) - Google Analytics