`
石不易
  • 浏览: 7720 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

【JavaScript 封装库】BETA 4.0 测试版发布!

阅读更多

 

/*
	源码作者: 石不易(Louis Shi)
	联系方式: http://www.shibuyi.net
	===================================================================================
	程序名称: JavaScript 封装库 BETA 4.0 版
	迭代版本: BETA 3.0
	插件总数: 12 个
	库方法数: 26 个
	功能总数: 67 个
	新增总数: 22 个
	删除总数: 3 个
	追加功能: 
		1. 进一步完善“获取元素节点”的功能, 包括: 前后位兄弟节点、子节点、父节点
		2. 新增“获取元素节点尺寸”, 可直接输出元素的宽高和坐标
		3. 库方法: 新增对 CSS 样式原生风格的解析, 支持 JavaScript 与 CSS 的两种; 例如: fontSize 也可写作 font-size
		4. 插件: 新增“元素动画”特效, 支持常规的宽高运动、坐标运动和透明度渐变; 另外也可自定义, 但必须要有对应像素单位的样式, 否则无效
		5. 插件: 新增“事件切换器”特效, 支持任意方法数, 点击元素后迭代切换事件
		...
	优化功能: 
		1. 优化了 CSS 解析功能, 支持原生和 JavaScript 两种写法, 可任意混合搭配
		2. 优化了“移除样式规则”, 从原先的索引下标移除转变为直接输入对应选择器名称即可删除, 但 W3C 与 IE 6/7/8 在选择器多重叠加上的解释并不一致, 需谨慎使用
		2. 优化了“自动加载插件”, 载入插件时直接将插件方法名变量传入即可, 但不支持匿名函数赋值给变量后在传入的写法
		4. 插件: 优化了“元素居中”特效, 现已支持 3 种居中方式: 水平居中、垂直居中、水平+垂直居中
		...
	删除功能: 
		1. 库方法: 删除了“初始化滚动条”方法, 今后直接通过“滚动条”方法设置即可
		2. 库方法: 删除了“CSS 处理”方法, 与“添加元素节点属性”结合, 无需再分离调用
		3. 库方法: 删除了“class 处理”方法, 与“添加元素节点属性”结合, 无需再分离调用
*/

// 实例化基础库
var $ = function () {
	var nodes = [];
	for (var i = 0; i < arguments.length; i ++) {
		nodes.push(arguments[i]);
	}
	return new Base(nodes);
};

// 基础库构造方法
var Base = function (nodes) {
	this.info = '无节点';
	this.elements = [];
	if (nodes instanceof Array) {
		var node = null, patternSpace = /[\s\t ]+/, elements = [], elementsList = [];
		for (var i = 0; i < nodes.length; i ++) {
			node = nodes[i];
			if (typeof node == 'string') { // 节点选择器
				if ((node = Base.trim(node)) == '') continue;
				if (patternSpace.test(node)) { // 多层
					elements = node.split(patternSpace);
				} else { // 单层
					elements.push(node);
				}
				for (var j = 0; j < elements.length; j ++) {
					if (this.selector(elements[j]).getNodes() == this.info) break;
				}
				for (var k = 0; k < this.elements.length; k ++) {
					elementsList.push(this.elements[k]);
				}
				this.elements = [], elements = [];
			} else if (Base.checkNode(node) || node === window) {
				elementsList.push(node);
			} else if (typeof node == 'function') { // HTML DOM
				this.loaded(node);
			}
		}
		this.elements = elementsList;
	}
};

// 元素节点选择器
Base.prototype.selector = function (selector) {
	if (typeof selector != 'string') {
		this.elements = [];
		return this;
	}
	selector = Base.trim(selector);
	var nodes = null, elements = [];
	if (this.elements.length == 0) this.elements.push(document);
	switch (selector.charAt(0)) {
		case '#' : // id
			selector = selector.substring(1);
			for (var i = 0; i < this.elements.length; i ++) {
				if ((nodes = $().getId(selector, this.elements[i]).getNodes()) != this.info) elements.push(nodes);
			}
			break;
		case '.' : // class
			selector = selector.substring(1);
			for (var i = 0; i < this.elements.length; i ++) {
				if ((nodes = $().getClass(selector, this.elements[i]).getNodes()) != this.info) {
					if (nodes instanceof Array) { // 集群
						for (var j = 0; j < nodes.length; j ++) {
							elements.push(nodes[j]);
						}
					} else { // 单一
						elements.push(nodes);
					}
				}
			}
			break;
		default : // tagName
			var patternId = /^(\w+)#([\-\w]+)$/i, patternClass = /^(\w+)\.([\-\w]+)$/i;
			if (patternId.test(selector)) { // tagName + id
				var tagName = patternId.exec(selector)[1];
				var id = patternId.exec(selector)[2];
				for (var i = 0; i < this.elements.length; i ++) {
					if ((nodes = $().getTagName(tagName, this.elements[i]).getNodes()) != this.info) {
						if (nodes instanceof Array) { // 集群
							for (var j = 0; j < nodes.length; j ++) {
								if (nodes[j].id == id) elements.push(nodes[j]);
							}
						} else { // 单一
							if (nodes.id == id) elements.push(nodes);
						}
					}
				}
			} else if (patternClass.test(selector)) { // tagName + class
				var tagName = patternClass.exec(selector)[1];
				var className = patternClass.exec(selector)[2];
				for (var i = 0; i < this.elements.length; i ++) {
					if ((nodes = $().getTagName(tagName, this.elements[i]).getNodes()) != this.info) {
						if (nodes instanceof Array) { // 集群
							for (var j = 0; j < nodes.length; j ++) {
								if (Base.hasClass(className, nodes[j])) elements.push(nodes[j]);
							}
						} else { // 单一
							if (Base.hasClass(className, nodes)) elements.push(nodes);
						}
					}
				}
			} else { // tagName
				for (var i = 0; i < this.elements.length; i ++) {
					 if ((nodes = $().getTagName(selector, this.elements[i]).getNodes()) != this.info) {
						if (nodes instanceof Array) { // 集群
							for (var j = 0; j < nodes.length; j ++) {
								elements.push(nodes[j]);
							}
						} else { // 单一
							elements.push(nodes);
						}
					 }
				}
			}
	}
	this.elements = elements;
	return this;
};

// 获取 id 元素节点
Base.prototype.getId = function (ids, positioner) {
	if (ids instanceof Array) { // 集群
		for (var i = 0; i < ids.length; i ++) {
			this.getId(ids[i], positioner);
		}
	} else { // 单一
		for (var k = 0; k < this.elements.length; k ++) {
			if (this.elements[k].id == ids) return this;
		}
		var selector = null, node = null;
		selector = Base.targetNode(positioner);
		if (selector === false) return this;
		if (selector instanceof Array) { // 集群
			for (var i = 0; i < selector.length; i ++) {
				node = selector[i].getElementsByTagName('*');
				for (var j = 0; j < node.length; j ++) {
					if (node[j].id == ids) {
						this.elements.push(node[j]);
					}
				}
			}
		} else { // 单一
			node = selector.getElementsByTagName('*');
			for (var i = 0; i < node.length; i ++) {
				if (node[i].id == ids) this.elements.push(node[i]);
			}
		}
	}
	return this;
};

// 获取 tagName 元素节点
Base.prototype.getTagName = function (tagName, positioner) {
	var selector  = null, node = null;
	selector = Base.targetNode(positioner);
	if (selector === false) return this;
	if (selector instanceof Array) { // 集群
		for (var i = 0; i < selector.length; i ++) {
			node = selector[i].getElementsByTagName(tagName);
			for (var j = 0; j < node.length; j ++) {
				this.elements.push(node[j]);
			}
		}
	} else { // 单一
		node = selector.getElementsByTagName(tagName);
		for (var i = 0; i < node.length; i ++) {
			this.elements.push(node[i]);
		}
	}
	return this;
};

// 获取 class 元素节点
Base.prototype.getClass = function (className, positioner) {
	var selector = null, node = null;
	selector = Base.targetNode(positioner);
	if (selector === false) return this;
	if (selector instanceof Array) { // 集群
		for (var i = 0; i < selector.length; i ++) {
			node = selector[i].getElementsByTagName('*');
			for (var j = 0; j < node.length; j ++) {
				if (Base.hasClass(className, node[j])) this.elements.push(node[j]);
			}
		}
	} else { // 单一
		node = selector.getElementsByTagName('*');
		for (var i = 0; i < node.length; i ++) {
			if (Base.hasClass(className, node[i])) this.elements.push(node[i]);
		}
	}
	return this;
};

// 获取 name 元素节点
Base.prototype.getName = function (name, positioner) {
	var selector = null, node= null;
	selector = Base.targetNode(positioner);
	if (selector === false) return this;
	if (selector instanceof Array) { // 集群
		for (var i = 0; i < selector.length; i ++) {
			node = selector[i].getElementsByTagName('*');
			for (var j = 0; j < node.length; j ++) {
				if (node[j].name == name) this.elements.push(node[j]);
			}
		}
	} else { // 单一
		node = selector.getElementsByTagName('*');
		for (var i = 0; i < node.length; i ++) {
			if (node[i].name == name) this.elements.push(node[i]);
		}
	}
	return this;
};

// 返回元素节点
Base.prototype.getNodes = function () {
	if (this.elements.length == 0) return this.info;
	if (this.elements.length == 1) return this.elements[0];
	return this.elements;
};

// 返回第一个元素节点
Base.prototype.firstNode = function () {
	if (this.elements.length == 0) return this.info;
	return this.elements[0];
};

// 返回最后一个元素节点
Base.prototype.lastNode = function () {
	if (this.elements.length == 0) return this.info;
	return this.elements[this.elements.length - 1];
};

// 获取第一个子元素节点
Base.prototype.firstChild = function () {
	var childs = [];
	var length = this.elements.length - 1;
	for (var i = length; i >= 0; i --) {
		Base.space(Base.comment(this.elements[i]));
		if (!(childs = Base.getChilds(this.elements[i]))) {
			this.elements.splice(i, 1);
			continue;
		}
		this.elements[i] = childs[0];
	}
	return this;
};

// 获取最后一个子元素节点
Base.prototype.lastChild = function () {
	var childs = [];
	var length = this.elements.length - 1;
	for (var i = length; i >= 0; i --) {
		Base.space(Base.comment(this.elements[i]));
		if (!(childs = Base.getChilds(this.elements[i]))) {
			this.elements.splice(i, 1);
			continue;
		}
		this.elements[i] = childs[childs.length - 1];
	}
	return this;
};

// 获取子元素节点
Base.prototype.childNodes = function () {
	var childs = [];
	var length = this.elements.length - 1;
	for (var i = length; i >= 0; i --) {
		Base.space(Base.comment(this.elements[i]));
		childs = Base.getChilds(this.elements[i])
		this.elements.splice(i, 1);
		if (!childs) continue;
		for (var j = 0; j < childs.length; j ++) {
			this.elements.splice(i + j, 0, childs[j]);
		}
	}
	return this;
};

// 获取上一位兄弟节点
Base.prototype.previousNode = function () {
	var length = this.elements.length - 1;
	for (var i = length; i >= 0; i --) {
		Base.space(Base.comment(this.elements[i].parentNode));
		if (!(this.elements[i] = Base.siblingNode(this.elements[i], false))) this.elements.splice(i, 1);
	}
	return this;
};

// 获取下一位兄弟节点
Base.prototype.nextNode = function () {
	var length = this.elements.length - 1;
	for (var i = length; i >= 0; i --) {
		Base.space(Base.comment(this.elements[i].parentNode));
		if (!(this.elements[i] = Base.siblingNode(this.elements[i], true))) this.elements.splice(i, 1);
	}
	return this;
};

// 获取之前所有兄弟节点
Base.prototype.previousAllNode = function () {
	var length = this.elements.length - 1;
	var siblings = [];
	for (var i = length; i >= 0; i --) {
		Base.space(Base.comment(this.elements[i].parentNode));
		if (!(this.elements[i] = Base.siblingNode(this.elements[i], false))) {
			this.elements.splice(i, 1);
			for (var j = 0; j < siblings.length; j ++) {
				this.elements.splice(i + j, 0, siblings[j]);
			}
			siblings = [];
		} else {
			siblings.push(this.elements[i]);
			i ++;
		}
	}
	return this;
};

// 获取之后所有兄弟节点
Base.prototype.nextAllNode = function () {
	var length = this.elements.length - 1;
	var siblings = [];
	for (var i = length; i >= 0; i --) {
		Base.space((Base.comment(this.elements[i].parentNode)));
		if (!(this.elements[i] = Base.siblingNode(this.elements[i]))) {
			this.elements.splice(i, 1);
			for (var j = 0; j < siblings.length; j ++) {
				this.elements.splice(i + j, 0, siblings[j]);
			}
			siblings = [];
		} else {
			siblings.push(this.elements[i]);
			i ++;
		}
	}
	return this;
};

// 获取父级元素节点
Base.prototype.parentNode = function () {
	var length = this.elements.length - 1;
	for (var i = length; i >= 0; i --) {
		if (!Base.checkNode(this.elements[i]) || this.elements[i].parentNode === null) {
			this.elements.splice(i, 1);
			continue;
		}
		this.elements[i] = this.elements[i].parentNode;
	}
	return this;
};

// 设置与获取元素内容
Base.prototype.html = function (text) {
	var html = [];
	for (var i = 0; i < this.elements.length; i ++) {
		if (typeof text != 'undefined') { // 设置
			this.elements[i].innerHTML = text;
		} else { // 获取
			html.push(this.elements[i].innerHTML);
		}
	}
	switch (html.length) {
		case 0 :
			return this;
			break;
		case 1 :
			return html[0];
			break;
		default : 
			return html;
	}
};

// 设置与获取表单内容
Base.prototype.value = function (text) {
	var value = [];
	for (var i = 0; i < this.elements.length; i ++) {
		if (typeof this.elements[i].value == 'undefined') continue;
		if (typeof text != 'undefined') { // 设置
			this.elements[i].value = text;
		} else { // 获取
			value.push(this.elements[i].value);
		}
	}
	switch (value.length) {
		case 0 :
			return this;
			break;
		case 1 :
			return value[0];
			break;
		default : 
			return value;
	}
};

// 设置与获取元素样式
Base.prototype.css = function (cssKey, cssValue) {
	var css = [], isList = false;
	var patternCss = /^([a-z\-\s]+)([\s\t ]*)(=|:)\2([\s\w\-\.\\\/\'\"#%\(\)=]+);?$/i;
	var key = '', value = '';
	cssValue = Base.trim(cssValue);
	if (!(isList = cssKey instanceof Array)) cssKey = Base.trim(cssKey); 
	for (var i = 0; i < this.elements.length; i ++) {
		if (typeof cssValue != 'undefined' || isList) { // 设置
			if (isList) { // 集群
				for (var j = 0; j < cssKey.length; j ++) {
					cssKey[j] = Base.trim(cssKey[j]);
					if (patternCss.test(cssKey[j])) {
						key = Base.toStyle(Base.trim(patternCss.exec(cssKey[j])[1]));
						value = Base.trim(patternCss.exec(cssKey[j])[4]);
						this.elements[i].style[key] = value;
					}
				}
			} else { // 单一
				cssKey = Base.toStyle(Base.trim(cssKey));
				this.elements[i].style[cssKey] = cssValue;
			}
		} else { // 获取
			css.push(Tool.getStyle(cssKey, this.elements[i]));
		}
	}
	switch (css.length) {
		case 0 :
			return this;
			break;
		case 1 : 
			return css[0];
			break;
		default : 
			return css;
	}
};

// 添加 class 选择器
Base.prototype.addClass = function (className) {
	if (typeof className == 'undefined') return this;
	className = Base.trim(className);
	if (arguments.length == 1) { // 单一
		var space = '';
		for (var i = 0; i < this.elements.length; i ++) {
			if (this.elements[i].className != '') space = ' ';
			if (!Base.hasClass(className, this.elements[i])) this.elements[i].className += space + className;
			space = '';
		}
	} else { // 集群
		for (var i = 0; i < arguments.length; i ++) {
			this.addClass(arguments[i]);
		}
	}
	return this;
};

// 移除 class 选择器
Base.prototype.removeClass = function (className) {
	if (typeof className == 'undefined') return this;
	className = Base.trim(className);
	if (arguments.length == 1) { // 单一
		for (var i = 0; i < this.elements.length; i ++) {
			if (Base.hasClass(className, this.elements[i])) {
				this.elements[i].className = this.elements[i].className.replace(new RegExp('(^|\\s+)' + className + '(\\s+|$)'), ' ');
				this.elements[i].className = Base.trim(this.elements[i].className);
			}
		}
	} else { // 集群
		for (var i = 0; i < arguments.length; i ++) {
			this.removeClass(arguments[i]);
		}
	}
	return this;
};

// 添加样式规则
Base.prototype.addRule = function (ruleName, ruleText, positioner, sheetIndex) {
	var rule = null;
	if (!(rule = Base.checkRule(positioner, sheetIndex))) return this;
	if (ruleName instanceof Array) { // 集群
		var patternRule = /^([\w\-#\.:,\s]+)[\s\t ]*\{([\s\w\-\.\\\/\'\"#%\(\)=:;]+)\}$/i;
		var _rule = null;
		for (var i = 0; i < ruleName.length; i ++) {
			_rule = Base.trim(ruleName[i]);
			if (patternRule.test(_rule)) {
				this.addRule(patternRule.exec(_rule)[1], patternRule.exec(_rule)[2], positioner, sheetIndex);
			}
		}
	} else { // 单一
		ruleText = Base.trim(ruleText);
		if (ruleName.indexOf(',') != -1) {
			ruleName = ruleName.split(',');
			for (var i = 0 ; i < ruleName.length; i ++) {
				ruleName[i] = Base.trim(ruleName[i]);
				if (ruleName[i] == '') continue;
				Tool.addRule(rule.sheet, ruleName[i], ruleText, rule.positioner);
			}
		} else {
			ruleName = Base.trim(ruleName);
			if (ruleName == '') return this;
			Tool.addRule(rule.sheet, ruleName, ruleText, rule.positioner);
		}
	}
	return this;
};

// 移除样式规则
Base.prototype.removeRule = function (ruleName, sheetIndex) {
	var rule = null;
	if (!(rule = Base.checkRule(null, sheetIndex))) return this;
	if (ruleName instanceof Array) { // 集群
		for (var i = 0; i < ruleName.length; i ++) {
			this.removeRule(ruleName[i], sheetIndex);
		}
	} else { // 单一
		var nameList = Tool.ruleName(rule.sheet);
		ruleName = Base.trim(ruleName.toLowerCase());
		var patternName = '';
		switch (ruleName.charAt(0)) {
			case '#' : // id
				patternName = '(^|\\s+|[a-z]+)' + ruleName + '(:[a-z]+)*($|,)';
				break;
			case '.' : // class
				patternName = '(^|\\s+|[a-z]+)' + ruleName + '(:[a-z]+)*($|,)';
				break;
			default : // tagName
				patternName = '(^|\\s+)' + ruleName + '(:[a-z]+)*($|,)';
				break;
		}
		for (var i = nameList.length - 1; i >= 0; i --) {
			nameList[i] = Base.trim(nameList[i].toLowerCase());
			if ((new RegExp(patternName, 'i')).test(nameList[i])) Tool.removeRule(rule.sheet, i);
		}
	}
	return this;
};

// 获取元素尺寸信息
Base.prototype.getSize = function () {
	var elementNode = null, innerRectangle = null, outerRectangle = null, size = [];
	for (var i = 0; i < this.elements.length; i ++)	{
		elementNode = this.elements[i];
		innerRectangle = Base.getInnerRectangle(elementNode);
		outerRectangle = Base.getOuterRectangle(elementNode);
		size.push({
			width : innerRectangle.width,
			height : innerRectangle.height,
			x : outerRectangle.left,
			y : outerRectangle.top
		});
	}
	switch (size.length) {
		case 0 : 
			return this;
			break;
		case 1 :
			return size[0];
			break;
		default : 
			return size;
	}
};

// 元素事件绑定
Base.prototype.nodeEvent = function (eventName, method, mode) {
	if (typeof eventName != 'string' || typeof method != 'function') return this;
	eventName = eventName.toLowerCase();
	if (eventName.indexOf('on') == 0) eventName = eventName.substring(2);
	if (typeof mode == 'undefined') mode = true;
	for (var i = 0; i < this.elements.length; i ++) {
		switch (eventName) {
			case 'scroll' : // 滚动条事件
				Tool.scroll(this.elements[i], method, !!mode);
				break;
			case 'mousewheel' : // 鼠标滚轮事件
				Tool.mousewheel(this.elements[i], method, !!mode);
				break;
			case 'mouseover' : // 鼠标移入
				Tool.mouseover(this.elements[i], method, !!mode);
				break;
			case 'mouseout' : // 鼠标移出
				Tool.mouseout(this.elements[i], method, !!mode);
				break;
			default : // 其他事件
				!!mode ? Tool.loginEvent(this.elements[i], eventName, method) : Tool.logoutEvent(this.elements[i], eventName, method);
		}
	}
	return this;
};

// HTML DOM 加载
Base.prototype.loaded = function (method) {
	if (typeof method != 'function') return this;
	Tool.loaded(method);
	return this;
};

// 自动加载插件
Base.prototype.plugins = function () {
	var plugins = arguments;
	if (plugins.length != 0) {
		var pluginName = '';
		for (var i = 0; i < plugins.length; i ++) {
			if (!(pluginName = Base.getMethodName(plugins[i]))) continue;
			Base.prototype[pluginName] = plugins[i];
		}
	}
	return this;
};

/*
	库方法集合
*/
// 库方法: 检测元素内容是否为空
Base.empty = function (elementNode) {
	elementNode = this.comment(elementNode);
	var text = this.trim($(elementNode).html());
	return text == '';
};

// 库方法: 获取方法名称
Base.getMethodName = function (method) {
	var patternMethodName  = /^function\s([\$\w]+)\(/i;
	if (typeof method != 'function' || !patternMethodName.test(method.toString())) return false;
	return patternMethodName.exec(method.toString())[1];
};

// 库方法: 禁止页面滚动(浏览器 BUG 修正)
Base.fixed = function (elementNode) {
	// 兼容 IE
	$(elementNode).nodeEvent('mousedown', function () {
		var scroll = Base.scroll();
		$(document.documentElement).nodeEvent('mouseup', function () {
			Base.scroll(scroll.x, scroll.y);
			$(this).nodeEvent('mouseup', arguments.callee, false);
		});
	});
	// 兼容 Chrome
	$(elementNode).nodeEvent('mousewheel', function () {});
};

// 库方法: 动画参数容错处理
Base.checkAnimation = function (animation, elementNode) {
	// 动画参数对象容错处理
	if (typeof animation != 'object') return false;
	
	// 动画缓冲开关容错处理
	if (typeof animation.isBuffer != 'undefined') {
		animation.isBuffer = !!animation.isBuffer;
	} else {
		animation.isBuffer = false;
	}
	
	// 动画缓冲速率容错处理
	animation.speed = Math.abs(this.number(animation.speed, 20));
	
	// 动画迭代毫秒数容错处理
	animation.time = Math.abs(this.number(animation.time, 30));
	
	// 动画列队容错处理
	if (typeof animation.method != 'function') {
		animation.method = function () {};
	}
	
	// 动画增减量容错处理
	animation.value = this.number(animation.value, false);
	
	// 动画步长值容错处理
	animation.step = Math.abs(this.number(animation.step, 10));
	
	// 同步动画容错处理
	if (typeof animation.multiple != 'object') animation.multiple = {};
	
	function checkAction(action) {
		if (typeof action != 'string') return false;
		action = Base.trim(action.toLowerCase());
		switch (action) {
			case 'x' : 
			case 'l' :
				action = 'left';
				break;
			case 'y' :
			case 't' :
				action = 'top';
				break;
			case 'w' :
				action = 'width';
				break;
			case 'h' :
				action = 'height';
				break;
			case 'o' :
				action = 'opacity';
				break;
			default :
				action = Base.toStyle(action);
		}
		return action;
	}
	
	function checkStart(start, action) {
		start = Base.trim(start);
		return Base.number(start, function () {
			if (/^(left)|(top)$/.test(action)) 	Base.absolute(elementNode);
			if (action == 'opacity') {
				if (browserDetect.ie && browserDetect.browser.version < 9) {
					var opacity = Base.trim($(elementNode).css('filter'));
					var patternOpacity = /alpha\(opacity([\s\t ]*)=\1(\d+)\)/i;
					if (patternOpacity.test(opacity)) {
						return patternOpacity.exec(opacity)[2];
					} else {
						return 100;
					}
				} else {
					return $(elementNode).css('opacity') * 100;
				}
			} else {
				return parseInt(Base.replace($(elementNode).css(action), 'px'));
			}
		});
	}
	
	function checkTarget(target) {
		target = Base.trim(target);
		return Base.number(target, function () {
			return animation.value === false ? animation.value : animation.start + animation.value;
		});
	}
	
	function checkOpacity(value) {
		if (value < 0) value = 0;
		if (value > 100) value = 100;
		return value;
	}
	
	for (var key in animation.multiple) {}
	
	// 检测是否同步动画
	if (typeof key == 'undefined') { // 单一动画
		
		// 动画运动方式容错处理
		animation.action = checkAction(animation.action);
		
		if (animation.action === false) return false;
		
		// 动画初始值容错处理
		animation.start = checkStart(animation.start, animation.action);
		
		// 动画目标量容错处理
		animation.target = checkTarget(animation.target);
		
		if (animation.action == 'opacity') {
			animation.start = checkOpacity(animation.start);
			animation.target = checkOpacity(animation.target);
		}
		if (animation.target === false || animation.start == animation.target) return false;
		
		if (animation.start > animation.target) animation.step = -animation.step;
		
		// 容错机制
		if (animation.start == 0) animation.start = 1;
		
		animation.action = [animation.action];
		animation.start = [animation.start];
		animation.target = [animation.target];
		animation.step = [animation.step];
	} else { // 同步动画
		// 遍历同步动画
		animation.action = [];
		animation.start = [];
		animation.target = [];
		var id = 0, value = '', patternValue = /^([\d\.]+)([\s\t ]*)=>\2([\d\.]+)$/;
		var action = '', start = 0, target = 0, step = animation.step;
		animation.step = [];
		for (var i in animation.multiple) {
			value = Base.trim(animation.multiple[i]);
			action = checkAction(i);
			if (patternValue.test(value)) { // 初始值 + 目标量
				start = checkStart(patternValue.exec(value)[1], action);
				target = checkTarget(patternValue.exec(value)[3]);
			} else { // 目标量
				start = checkStart(null, action);
				target = checkTarget(value);
			}
			if (action == 'opacity') {
				start = checkOpacity(start);
				target = checkOpacity(target);
			}
			if (target === false || target == start) continue;
			
			// 容错机制
			if (start == 0) start = 1;
		
			animation.action[id] = action;
			animation.start[id] = start;
			animation.target[id] = target;
			animation.step[id] = start > target ? -step : step;
			id ++;
		}
	}
	return animation;
};

// 库方法: 数字转换
Base.number = function (number, replace) {
	if (typeof number != 'undefined' && !isNaN(parseInt(number))) {
		return parseInt(number);
	} else {
		switch (typeof replace) {
			case 'undefined' :
				return 0;
				break;
			case 'function' : 
				return replace();
				break;
			default : 
				return replace;
		}
	}
};

// 库方法: 添加元素节点属性
Base.attribute = function (attributes, elementNode) {
	if (attributes instanceof Array) { // 集群
		for (var i = 0; i < attributes.length; i ++) {
			this.attribute(attributes[i], elementNode);
		}
	} else { // 单一
		attributes = this.trim(attributes);
		var patternAttribute = /^([a-z]+)([\s\t ]*)=\2([=\w\'\":;\.\\\/\-%#\(\)\s]+)$/i, key = '', value = '';
		if (patternAttribute.test(attributes)) {
			key = patternAttribute.exec(attributes)[1];
			value = patternAttribute.exec(attributes)[3];
			if (/^class(Name)?$/i.test(key)) { // class
				var patternSpace = /[\s\t ]+/;
				if (patternSpace.test(value)) { // 集群
					var valueList = value.split(patternSpace);
					for (var i = 0; i < valueList.length; i ++) {
						if (valueList[i] == '') continue;
						$(elementNode).addClass(valueList[i]);
					}
				} else { // 单一
					$(elementNode).addClass(value);
				}
			} else if (key == 'style') { // css
				var patternSpace = /;[\s\t ]*/;
				if (patternSpace.test(value)) { // 集群
					var valueList = value.split(patternSpace);
					$(elementNode).css(valueList);
				} else { // 单一
					$(elementNode).css([value]);
				}
			} else {
				elementNode.setAttribute(key, value);
			}
		}
	}
	return elementNode;
};

// 库方法: 获取元素兄弟节点
Base.siblingNode = function (elementNode, siblingMode) {
	if (!this.checkNode(elementNode) && elementNode.nodeType != 3) return false;
	if (typeof siblingMode == 'undefined') siblingMode = true;
	siblingNode = !!siblingMode ? elementNode.nextSibling : elementNode.previousSibling;
	if (siblingNode === null) {
		return false;
	} else if (siblingNode.nodeType != 1) {
		return this.siblingNode(siblingNode, siblingMode);
	} else {
		return siblingNode;
	}
};

// 库方法: 添加节点对象
Base.addElement = function (elementName, attributes, htmlText, elementTarget) {
	if (typeof elementName != 'string') return false;
	var elementNode = document.createElement(elementName);
	if (typeof attributes == 'string' || attributes instanceof Array) this.attribute(attributes, elementNode);
	if (typeof htmlText != 'undefined' && htmlText !== null) $(elementNode).html(htmlText);
	if (typeof elementTarget == 'undefined' || !(elementTarget = this.targetNode(elementTarget))) elementTarget = document.body;
	var nodes = [];
	if (elementTarget instanceof Array) { // 集群
		for (var i = 0; i < elementTarget.length; i ++) {
			nodes.push(elementTarget[i].appendChild(elementNode.cloneNode(true)));
		}
	} else { // 单一
		nodes.push(elementTarget.appendChild(elementNode));
	}
	return nodes.length == 1 ? nodes[0] : nodes;
};

// 库方法: 移除节点对象
Base.removeElement = function (elementNode, elementTarget) {
	if (typeof elementNode == 'undefined' || (!(elementNode instanceof Array) && !(elementNode = this.targetNode(elementNode)))) return false;
	if (typeof elementTarget == 'undefined' || (!(elementTarget instanceof Array) && !(elementTarget = this.targetNode(elementTarget)))) elementTarget = false;
	if (elementTarget instanceof Array) {
		for (var i = 0; i < elementTarget.length; i ++) {
			this.removeElement(elementNode, elementTarget[i]);
		}
	} else {
		if (elementNode instanceof Array) {
			for (var i = 0; i < elementNode.length; i ++) {
				this.removeElement(elementNode[i], elementTarget);
			}
		} else {
			if (elementTarget === false) elementTarget = elementNode.parentNode;
			if (this.contains(elementNode, elementTarget)) elementTarget.removeChild(elementNode);
		}
	}
};

// 库方法: 元素直接从属关系
Base.contains = function (elementNode, elementTarget) {
	if (!this.checkNode(elementNode) || !this.checkNode(elementTarget)) return false;
	var children = elementTarget.childNodes;
	for (var i = 0; i < children.length; i ++) {
		if (children[i] == elementNode) return true;
	}
	return false;
};

// 库方法: 获取浏览器可视区域大小
Base.getWindowRectangle = function () {
	return {
		width : Tool.getWindowWidth(),
		height : Tool.getWindowHeight()
	}
};

// 库方法: 获取元素内部区域大小
Base.getInnerRectangle = function (elementNode) {
	var _this = $(elementNode);
	var display = _this.css('display');
	var width = 0, height = 0;
	if (display != 'none') {
		width = elementNode.offsetWidth;
		height = elementNode.offsetHeight;
	} else {
		width = this.number(this.replace(_this.css('width'), 'px'));
		height = this.number(this.replace(_this.css('height'), 'px'));
	}
	return {
		width : width,
		height : height
	}
};

// 库方法: 获取元素外部区域大小
Base.getOuterRectangle = function (elementNode) {
	var _this = $(elementNode);
	var display = _this.css('display');
	var left = 0, top = 0;
	if (display != 'none') {
		left = elementNode.offsetLeft;
		top = elementNode.offsetTop;
	} else {
		this.absolute(elementNode);
		left = this.number(this.replace(_this.css('left'), 'px'));
		top = this.number(this.replace(_this.css('top'), 'px'));
	}
	return {
		left : left,
		top : top
	}
};

// 库方法: 设置元素绝对定位
Base.absolute = function (elementNode) {
	var _this = $(elementNode);
	if (_this.css('position') == 'static') _this.css('position', 'absolute');
};

// 库方法: 样式风格转换
Base.toStyle = function (cssKey) {
	if (typeof cssKey != 'string') return cssKey;
	if (cssKey.indexOf('-') != -1) {
		var keyList = cssKey.split('-');
		for (var i = 0; i < keyList.length; i ++) {
			if ((keyList[i] = Base.trim(keyList[i])) == '') continue;
			if (i == 0) {
				cssKey = keyList[i];
			} else {
				cssKey += keyList[i].charAt(0).toUpperCase() + keyList[i].substring(1);
			}
		}
	}
	return cssKey;
};

// 库方法: 获取目标节点
Base.targetNode = function (positioner) {
	var selector = null;
	if (typeof positioner != 'undefined') { // 局部
		if (this.checkNode(positioner)) {
			selector = positioner;
		} else {
			if (!(selector = this.positioner(positioner))) return false;
		}
	} else { // 全局
		selector = document;
	}
	return selector;
};

// 库方法: 获取与设置浏览器滚动条
Base.scroll = function (x, y) {
	if (typeof x == 'number') {
		Tool.scrollX(Math.abs(parseInt(x)));
	}
	if (typeof y == 'number') {
		Tool.scrollY(Math.abs(parseInt(y)));
	}
	return {
		x : Tool.scrollX(),
		y : Tool.scrollY()
	}
};

// 库方法: 检测样式规则参数
Base.checkRule = function (positioner, sheetIndex) {
	var sheets = document.styleSheets;
	if (typeof positioner == 'undefiend' || isNaN(positioner)) positioner = 0;
	if (typeof sheetIndex == 'undefined' || isNaN(sheetIndex)) sheetIndex = 0;
	if (sheetIndex >= sheets.length) sheetIndex = sheets.length - 1;
	sheetIndex = Math.abs(parseInt(sheetIndex));
	positioner = Math.abs(parseInt(positioner));
	if (typeof sheets[sheetIndex] == 'undefined' || typeof sheets[sheetIndex] == 'unknown') return false;
	var sheet = sheets[sheetIndex];
	var positionerMax = Tool.ruleTotal(sheet) - 1;
	if (positioner > positionerMax) positioner = positionerMax;
	return {
		positioner : positioner,
		sheet : sheet
	}
};

// 库方法: 检测 class
Base.hasClass = function (className, elementNode) {
	return (new RegExp('(^|\\s+)' + className + '(\\s+|$)', 'i')).test(elementNode.className);
};

// 库方法: 元素节点定位器
Base.positioner = function (selector) {
	if (typeof selector != 'string') return false;
	selector = this.trim(selector);
	var patternId = /^(id([\s\t ]*)=\2)?(\w+)$/i, 
		patternTag = /^tag(Name)?([\s\t ]*)=\2(\w+)$/i, 
		patternClass = /^class(Name)?([\s\t ]*)=\2(\w+)$/i;
	if (patternId.test(selector)) { // id node
		selector = patternId.exec(selector)[3];
		selector = $().getId(selector).getNodes();
	} else if (patternTag.test(selector)) { // tagName node
		selector = patternTag.exec(selector)[3];
		selector = $().getTagName(selector).getNodes();
	} else if (patternClass.test(selector)) { // class node
		selector = patternClass.exec(selector)[3];
		selector = $().getClass(selector).getNodes();
	}
	if (selector == $().info) return false;
	return selector;
};

// 库方法: 移除两边空格
Base.trim = function (string) {
	if (typeof string != 'string') return string;
	var spaceLeft = /^[\s\t ]+/, spaceRight = /[\s\t ]+$/;
	if (spaceLeft.test(string)) string = string.replace(spaceLeft, '');
	if (spaceRight.test(string)) string = string.replace(spaceRight, '');
	return string;
};

// 库方法: 移除指定字符串
Base.replace = function (string, index) {
	if (typeof string != 'string' || typeof index == 'undefined') return string;
	if (string.toLowerCase().indexOf(index.toLowerCase()) != -1) string = string.replace(new RegExp(index, 'gi'), '');
	return string;
};

// 库方法: 检测是否元素节点
Base.checkNode = function (elementNode) {
	if (elementNode === null 
	|| 
		typeof elementNode != 'object' 
	|| 
		typeof elementNode.nodeType != 'number' 
	|| 
		(elementNode.nodeType != 1 && elementNode.nodeType != 9)) return false;
	return true;
};

// 库方法: 移除空白节点
Base.space = function (elementNode) {
	if (!this.checkNode(elementNode)) return elementNode;
	var childs = elementNode.childNodes;
	var maxIndex = childs.length - 1;
	for (var i = maxIndex; i >= 0; i --) {
		if (childs[i].nodeType == 3 && /^[\s\t ]+$/.test(childs[i].nodeValue)) elementNode.removeChild(childs[i]);
	}
	return elementNode;
};

// 库方法: 移除注释节点
Base.comment = function (elementNode) {
	if (!this.checkNode(elementNode)) return elementNode;
	var childs = elementNode.childNodes;
	var maxIndex = childs.length - 1;
	for (var i = maxIndex; i >= 0; i --) {
		if (childs[i].nodeType == 8) elementNode.removeChild(childs[i]);
	}
	return elementNode;
};

// 库方法: 获取子元素节点
Base.getChilds = function (elementNode) {
	if (!this.checkNode(elementNode)) return false;
	var childs = elementNode.childNodes;
	var childList = [];
	for (var i = 0; i < childs.length; i ++) {
		if (childs[i].nodeType == 1) childList.push(childs[i]);
	}
	return childList.length != 0 ? childList : false;
};

 

/*
	源码作者: 石不易(Louis Shi)
	联系方式: http://www.shibuyi.net
	===================================================================================
	程序名称: JavaScript 工具库(跨浏览器兼容) BETA 4.0 版
	迭代版本: BETA 3.0
	功能总数: 21 个
	新增总数: 3 个
	删除总数: 0 个
	追加功能: 
		1. 新增“跨浏览器鼠标移入事件”, 解决元素对子元素的移入误判, 导致事件反复执行的BUG
		2. 新增“跨浏览器鼠标移出事件”, 解决元素对子元素的移出误判, 导致事件反复执行的BUG
		3. 新增“跨浏览器滚动条事件”, 解决 IE 6/7/8 无法识别 document 节点的滚动条事件
	优化功能: 
		1. 删除了“跨浏览器现代事件绑定: 注册事件”使用的唯一标识符, 直接用数组 push 方法添加
		2. 对“IE 6/7/8 专属: 匹配 W3C 事件 Event 对象”方法新增了 mouseover 与 mouseout 事件中获取周围元素的方法
	删除功能: 
		无
*/

var Tool = {
	// 数组排序
	sort : {
		minToMax : function (min, max) {
			if (min < max) {
				return -1;
			} else if (min > max) {
				return 1;
			} else {
				return 0;
			}
		},
		maxToMin : function (min, max) {
			if (min < max) {
				return 1;
			} else if (min > max) {
				return -1;
			} else {
				return 0;
			}
		}
	},
	
	// 跨浏览器获取计算后的样式
	getStyle : function (cssKey, elementNode) {
		if (typeof window.getComputedStyle != 'undefined') { // W3C
			return window.getComputedStyle(elementNode, null)[cssKey];
		} else if (typeof elementNode.currentStyle) { // IE 6/7/8
			return elementNode.currentStyle[cssKey];
		}
	},
	
	// 跨浏览器获取样式规则总数
	ruleTotal : function (sheet) {
		if (typeof sheet.cssRules != 'undefined') { // W3C
			return sheet.cssRules.length;
		} else if (typeof sheet.rules != 'undefined') { // IE 6/7/8
			return sheet.rules.length;
		}
	},
	
	// 跨浏览器获取样式规则名称
	ruleName : function (sheet) {
		var nameList = [], rules = null;
		if (typeof sheet.cssRules != 'undefined') { // W3C
		 	rules = sheet.cssRules;
		} else if (typeof sheet.rules != 'undefined') { // IE 6/7/8
			rules = sheet.rules;
		}
		for (var i = 0; i < rules.length; i ++) {
			nameList.push(rules[i].selectorText);
		}
		return nameList;
	},
	
	// 跨浏览器添加样式规则
	addRule : function (sheet, ruleName, ruleText, positioner) {
		if (typeof sheet.insertRule != 'undefined') { // W3C
			sheet.insertRule(ruleName + ' {' + ruleText + '}', positioner);
		} else if (typeof sheet.addRule != 'undefined') { // IE 6/7/8
			sheet.addRule(ruleName, ruleText, positioner);
		}
	},
	
	// 跨浏览器删除样式规则
	removeRule : function (sheet, positioner) {
		if (typeof sheet.deleteRule != 'undefined') { // W3C
			sheet.deleteRule(positioner);
		} else if (typeof sheet.removeRule != 'undefined') { // IE 6/7/8
			sheet.removeRule(positioner);
		}
	},
	
	// 跨浏览器现代事件绑定: 注册事件
	loginEvent : function (elementNode, eventName, method) {
		if (typeof elementNode.addEventListener != 'undefined') { // W3C
			elementNode.addEventListener(eventName, method, false);
		} else if (typeof elementNode.attachEvent != 'undefined') { // IE 6/7/8
			// 创建哈希表
			if (typeof elementNode.hashTable != 'object') elementNode.hashTable = {};
			// 创建事件数组
			if (!(elementNode.hashTable[eventName] instanceof Array)) elementNode.hashTable[eventName] = [];
			var events = elementNode.hashTable[eventName];
			// 检测方法是否重复
			for (var i = 0; i < events.length; i ++) {
				if (events[i] == method) return false;
			}
			// 存储事件方法
			events.push(method);
			var _this = this;
			// 执行事件
			elementNode['on' + eventName] = function () {
				var event = _this.eventIE(window.event);
				for (var i = 0; i < events.length; i ++) {
					events[i].call(this, event);
				}
			};
		}
	},
	
	// 跨浏览器现代事件绑定: 注销事件
	logoutEvent : function (elementNode, eventName, method) {
		if (typeof elementNode.removeEventListener != 'undefined') { // W3C
			elementNode.removeEventListener(eventName, method, false);
		} else if (typeof elementNode.detachEvent != 'undefined') { // IE 6/7/8
			if (typeof elementNode.hashTable != 'object' || !(elementNode.hashTable[eventName] instanceof Array)) return false;
			var events = elementNode.hashTable[eventName];
			for (var i = 0; i < events.length; i ++) {
				if (events[i] == method) events.splice(i, 1);
			}
		}
	},
	
	// IE 6/7/8 专属: 匹配 W3C 事件 Event 对象
	eventIE : function (event) {
		event.target = event.srcElement;
		event.preventDefault = function () {
			event.returnValue = false;
		};
		event.stopPropagation = function () {
			event.cancelBubble = true;
		};
		event.relatedTarget = function () {
			switch (event.type) {
				case 'mouseover' :
					return event.fromElement;
					break;
				case 'mouseout' : 
					return event.toElement;
					break;
				default :
					return null;
			}
		}();
		return event;
	},
	
	// 跨浏览器鼠标滚轮(鼠标中键)事件
	mousewheel : function (elementNode, method, mode) {
		if (elementNode == window) elementNode = document; // IE 6/7/8
		if (typeof elementNode.onmousewheel != 'undefined') { // Not Firefox
			mode ? this.loginEvent(elementNode, 'mousewheel', method) : this.logoutEvent(elementNode, 'mousewheel', method);
		} else { // Firefox
			mode ? this.loginEvent(elementNode, 'DOMMouseScroll', method) : this.logoutEvent(elementNode, 'DOMMouseScroll', method);
		}
	},
	
	// 跨浏览器鼠标移入事件
	mouseover : function (elementNode, method, mode) {
		mode ? this.loginEvent(elementNode, 'mouseover', function (event) {
			if (event.relatedTarget !== null && (event.relatedTarget == this || Tool.contains(event.relatedTarget, this))) return false;
			method.call(this, event);
		}) : this.logoutEvent(elementNode, 'mouseover', method);
	},
	
	// 跨浏览器鼠标移出事件
	mouseout : function (elementNode, method, mode) {
		mode ? this.loginEvent(elementNode, 'mouseout', function (event) {
			if (event.relatedTarget !== null && (event.relatedTarget == this || Tool.contains(event.relatedTarget, this))) return false;
			method.call(this, event);
		}) : this.logoutEvent(elementNode, 'mouseout', method);
	},
	
	// 跨浏览器滚动条事件
	scroll : function (elementNode, method, mode) {
		if (elementNode == document) this.scroll(document.documentElement, method, mode); // IE 6/7/8
		mode ? this.loginEvent(elementNode, 'scroll', method) : this.logoutEvent(elementNode, 'scroll', method);
	},
	
	// 跨浏览器设置与获取 X 轴滚动条
	scrollX : function (x) {
		var html = document.documentElement;
		var body = document.body;
		if (typeof x != 'undefined') { // 设置
			html.scrollLeft = x;
			body.scrollTop = x;
		} else { // 获取
			return html.scrollLeft == 0 ? body.scrollLeft : html.scrollLeft;
		}
	},
	
	// 跨浏览器设置与获取 Y 轴滚动条
	scrollY : function (y) {
		var html = document.documentElement;
		var body = document.body;
		if (typeof y != 'undefined') { // 设置
			html.scrollTop = y;
			body.scrollTop = y;
		} else { // 获取
			return html.scrollTop == 0 ? body.scrollTop : html.scrollTop;
		}
	},
	
	// 跨浏览器 HTML DOM 记载
	loaded : function (method) {
		if ((browserDetect.opera && browserDetect.browser.version < 9) 
		|| 
			(/WebKit/i.test(browserDetect.engine.name) && browserDetect.engine.version < 525) 
		|| 
			(browserDetect.firefox && browserDetect.browser.version < 3)) { // 低版本 W3C
			var timer = setTimeout(function () {
				clearTimeout(timer);
				if (!/^(loading)|(interactive)|(loaded)|(complete)$/i.test(document.readyState)) {
					timer = setTimeout(arguments.callee, 1); // 递归
				}
				method();
			}, 1);
			
		} else if (!/Trident/i.test(browserDetect.engine.name) || browserDetect.engine.version >= 5) { // 主流 W3C
			var _this = this;
			_this.loginEvent(document, 'DOMContentLoaded', function () {
				_this.logoutEvent(document, 'DOMContentLoaded', arguments.callee);
				method();
			});
		} else if (/Trident/i.test(browserDetect.engine.name) && browserDetect.engine.version < 5) { // IE 6/7/8
			var timer = setTimeout(function () {
				clearTimeout(timer);
				try {
					document.documentElement.doScroll('top');
					method();
				} catch(error) {
					timer = clearTimeout(arguments.callee, 1);
				}
			}, 1);
		}
	},
	
	// 跨浏览器检测元素从属关系(间接从属+直接从属)
	contains : function (elementNode, elementTarget) {
		if (typeof elementTarget.compareDocumentPosition != 'undefined') { // W3C
			return elementTarget.compareDocumentPosition(elementNode) == 20;
		} else if (typeof elementTarget.contains != 'undefined') { // IE 6/7/8
			return elementTarget.contains(elementNode);
		}
	},
	
	// 跨浏览器获取浏览器可视区域 X 轴大小
	getWindowWidth : function () {
		if (typeof window.innerWidth != 'undefined') { // W3C
			return window.innerWidth;
		} else if (typeof document.documentElement.clientWidth != 'undefined') { // IE 6/7/8
			return document.documentElement.clientWidth;
		}
	},
	
	// 跨浏览器获取浏览器可视区域 Y 轴大小
	getWindowHeight : function () {
		if (typeof window.innerHeight != 'undefined') { // W3C
			return window.innerHeight;
		} else if (typeof document.documentElement.clientHeight != 'undefined') { // IE 6/7/8
			return document.documentElement.clientHeight;
		}
	},
	
	// IE 专属: 浏览器外捕获鼠标按下
	setCaptureIE : function (elementNode) {
		if (typeof elementNode.setCapture != 'undefined') {
			elementNode.setCapture();
		}
	},
	
	// IE 专属: 浏览器外捕获鼠标松开
	releaseCaptureIE : function (elementNode) {
		if (typeof elementNode.releaseCapture != 'undefined') {
			elementNode.releaseCapture();
		}
	}
};

 

/*
	源码作者: 石不易(Louis Shi)
	联系方式: http://www.shibuyi.net
	===================================================================================
	程序名称: 浏览器嗅探器 BETA 4.0
	版本迭代: BETA 3.0
	功能总数: 4 个
	新增总数: 0 个
	删除总数: 0 个
	追加功能: 
		无
	优化功能: 
		1. 优化了 IE 浏览器版本的嗅探
	删除功能: 
		无
*/

// 浏览器嗅探器
(function () {

	window.browserDetect = {
		ie : false,
		firefox : false,
		chrome : false,
		safari : false,
		opera : false,
		other : false,
		
		browser : {
			name : '',
			version : 0
		},
		
		engine : {
			name : '',
			version : 0
		},
		
		system : {
			name : '',
			version : 0
		}
		
	};
	
	// 获取用户代理字符串
	var userAgent = navigator.userAgent;
	var platform = navigator.platform;
	
	var patternIELow = /MSIE\s([\.\d]+)/i;
	var patternIEHigh = /Trident(.+)rv:([\.\d]+)/i;
	var patternFirefox = /Firefox\/([\.\d]+)/i;
	var patternChrome = /Chrome\/([\.\d]+)/i;
	var patternSafari = /Safari\/([\.\d]+)/i;
	var patternOpera = /Opera\/([\.\d]+)/i;
	
	var patternTrident = /Trident\/([\.\d]+)/i;
	var patternVersion = /Version\/([\.\d]+)/i;
	
	// 嗅探浏览器型号
	if (patternIELow.test(userAgent) || patternIEHigh.test(userAgent)) { // IE
		browserDetect.ie = true;
		browserDetect.browser.name = 'Internet Explorer';
		// 浏览器版本
		if (patternIELow.test(userAgent)) { // IE 6~10
			browserDetect.browser.version = parseFloat(patternIELow.exec(userAgent)[1]);
		} else { // IE 11+
			browserDetect.browser.version = parseFloat(patternIEHigh.exec(userAgent)[2]);
		}
		browserDetect.engine.name = 'Trident';
		switch (browserDetect.browser.version) {
			case 6 :
				browserDetect.engine.version = 2;
				break;
			case 7 :
				browserDetect.engine.version = 3;
				break;
			default :
				browserDetect.engine.version = 'unknown';
		}
	} else if (patternFirefox.test(userAgent)) { // Firefox
		browserDetect.firefox = true;
		browserDetect.browser.name = 'Firefox';
		browserDetect.browser.version = parseFloat(patternFirefox.exec(userAgent)[1]);
	} else if (patternChrome.test(userAgent)) { // Chrome
		browserDetect.chrome = true;
		browserDetect.browser.name = 'Chrome';
		browserDetect.browser.version = parseFloat(patternChrome.exec(userAgent)[1]);
	} else if (patternSafari.test(userAgent)) { // Safari
		browserDetect.safari = true;
		browserDetect.browser.name = 'Safari';
		if (patternVersion.test(userAgent)) { // 高版本
			browserDetect.browser.version = parseFloat(patternVersion.exec(userAgent)[1]);
		} else { // 低版本
			browserDetect.browser.version = parseFloat(patternSafari.exec(userAgent)[1]);
		}
	} else if (patternOpera.test(userAgent)) { // Opera
		browserDetect.opera = true;
		browserDetect.browser.name = 'Opera';
		if (patternVersion.test(userAgent)) { // 高版本
			browserDetect.browser.version = parseFloat(patternVersion.exec(userAgent)[1]);
		} else { // 低版本
			browserDetect.browser.version = parseFloat(patternOpera.exec(userAgent)[1]);
		}
	} else { // Other
		browserDetect.other = true;
		browserDetect.browser.name = 'unknown';
		browserDetect.browser.version = 'unknown';
	}
	
	var patternGecko = /Gecko\/([\.\d]+)/i;
	var patternWebKit = /WebKit\/([\.\d]+)/i;
	var patternPresto = /Presto\/([\.\d]+)/i;
	
	// 嗅探浏览器内核(引擎)
	if (patternTrident.test(userAgent)) { // Trident
		browserDetect.engine.name = 'Trident';
		browserDetect.engine.version = parseFloat(patternTrident.exec(userAgent)[1]);
	} else if (patternGecko.test(userAgent)) { // Gecko
		browserDetect.engine.name = 'Gecko';
		patternVersion = /rv:([\.\d]+)/i;
		if (patternVersion.test(userAgent)) { // 高版本
			browserDetect.engine.version = parseFloat(patternVersion.exec(userAgent)[1]);
		} else { // 低版本
			browserDetect.engine.version = parseFloat(patternGecko.exec(userAgent)[1]);
		}
	} else if (patternWebKit.test(userAgent)) { // WebKit
		browserDetect.engine.name = 'WebKit';
		browserDetect.engine.version = parseFloat(patternWebKit.exec(userAgent)[1]);
	} else if (patternPresto.test(userAgent)) { // Presto
		browserDetect.engine.name = 'Presto';
		browserDetect.engine.version = parseFloat(patternPresto.exec(userAgent)[1]);
	} else if (!browserDetect.ie) { // Other
		browserDetect.engine.name = 'unknown';
		browserDetect.engine.version = 'unknown';
	}
	
	var patternWindows = /Windows\sNT\s([\.\d]+)/i;
	var patternWin = /Win/i;
	var patternLinux = /Linux/i;
	var patternUnix = /X11/i;
	var patternMac = /Mac/i;
	
	// 嗅探系统平台
	if (patternWindows.test(userAgent)) { // Windows (高版本浏览器)
		browserDetect.system.version = parseFloat(patternWindows.exec(userAgent)[1]);
		switch (browserDetect.system.version) {
			case 5.0 : 
				browserDetect.system.name = 'Windows 2000';
				break;
			case 5.1 : 
				browserDetect.system.name = 'Windows XP';
				break;
			case 5.2 : 
				browserDetect.system.name = 'Windows Server 2003 / Windows Server 2003 R2';
				break;
			case 6.0 : 
				browserDetect.system.name = 'Windows Vista / Windows Server 2008';
				break;
			case 6.1 : 
				browserDetect.system.name = 'Windows 7 / Windows Server 2008 R2';
				break;
			case 6.2 : 
				browserDetect.system.name = 'Windows 8 / Windows Server 2012 / Windows Phone 8';
				break;
			case 6.3 : 
				browserDetect.system.name = 'Windows 8.1 / Windows Server 2012 R2';
				break;
			default : 
				browserDetect.system.name = 'Windows';
		}
	} else if (patternWin.test(platform)) { // Windows (低版本浏览器)
		browserDetect.system.name = 'Windows';
		browserDetect.system.version = 'unknown';
	} else if (patternLinux.test(platform)) { // Linux
		browserDetect.system.name = 'Linux';
		browserDetect.system.version = 'unknown';
	} else if (patternUnix.test(platform)) { // Unix
		browserDetect.system.name = 'Unix';
		browserDetect.system.version = 'unknown';
	} else if (patternMac.test(platform)) { // Mac
		browserDetect.system.name = 'Macintosh';
		browserDetect.system.version = 'unknown';
	} else { // Other
		browserDetect.system.name = 'unknown';
		browserDetect.system.version = 'unknown';
	}
})();

 

/*
	源码作者: 石不易(Louis Shi)
	联系方式: http://www.shibuyi.net
	===================================================================================
	插件:
	1. 元素隐藏
	2. 元素显示
	3. 鼠标移入移出
*/

$().plugins(hide, show, hover);

// 元素隐藏
function hide() {
	this.css('display', 'none');
	return this;
}

// 元素显示
function show() {
	this.css('display', 'block');
	return this;
}

// 鼠标移入移出
function hover(overMethod, outMethod) {
	this.nodeEvent('mouseover', overMethod);
	this.nodeEvent('mouseout', outMethod);
	return this;
}

 

/*
	源码作者: 石不易(Louis Shi)
	联系方式: http://www.shibuyi.net
	===================================================================================
	插件:
	1. 元素垂直居中
	2. 元素水平居中
	3. 元素垂直水平居中
*/

$().plugins(yCenter, xCenter, center);

// 元素垂直居中
function yCenter(animationMode) {
	if (typeof animationMode == 'undefined') animationMode = false;
	var windowHeight = Base.getWindowRectangle().height;
	var innerHeight = 0, y = 0, elementNode = null;
	for (var i = 0; i < this.elements.length; i ++) {
		elementNode = this.elements[i];
		Base.absolute(elementNode);
		innerHeight = Base.getInnerRectangle(elementNode).height;
	 	y = (windowHeight - innerHeight) / 2;
		if (y < 0) y = 0;
		y += Base.scroll().y;
		if (!!animationMode) { // 动画模式
			$(elementNode).animation({
				action : 'y',
				target : y,
				isBuffer : true,
				speed : 10
			});
		} else {
			$(elementNode).css('top', y + 'px');
		}
	}
	return this;
}

// 元素水平居中
function xCenter(animationMode) {
	if (typeof animationMode == 'undefined') animationMode = false;
	var windowWidth = Base.getWindowRectangle().width;
	var innerWidth = 0, x = 0, elementNode = null;
	for (var i = 0; i < this.elements.length; i ++) {
		elementNode = this.elements[i];
		Base.absolute(elementNode);
		innerWidth = Base.getInnerRectangle(elementNode).width;
		x = (windowWidth - innerWidth) / 2;
		if (x < 0) x = 0;
		x += Base.scroll().x;
		if (!!animationMode) {
			$(elementNode).animation({
				action : 'x',
				target : x,
				isBuffer : true,
				speed : 10
			});
		} else {
			$(elementNode).css('left', x + 'px');
		}
	}
	return this;
}

// 元素垂直水平居中
function center(animationMode) {
	if (typeof animationMode == 'undefined') animationMode = false;
	var windowRectangle = Base.getWindowRectangle();
	var scroll = Base.scroll();
	var innerRectangle = 0, x = 0, y = 0, elementNode = null;
	for (var i = 0; i < this.elements.length; i ++) {
		elementNode = this.elements[i];
		Base.absolute(elementNode);
		innerRectangle = Base.getInnerRectangle(elementNode);
		x = (windowRectangle.width - innerRectangle.width) / 2;
		y = (windowRectangle.height - innerRectangle.height) / 2;
		if (x < 0) x = 0;
		if (y < 0) y = 0;
		x += scroll.x;
		y += scroll.y;
		if (!!animationMode) {
			$(elementNode).animation({
				multiple : {
					x : x,
					y : y
				},
				isBuffer : true,
				speed : 10
			});
		} else {
			$(elementNode).css(['left : '  + x + 'px', 'top : ' + y + 'px']);
		}
	}
	return this;
}

 

/*
	源码作者: 石不易(Louis Shi)
	联系方式: http://www.shibuyi.net
	===================================================================================
	插件:
	1. 遮罩锁屏
	2. 清除锁屏
*/

$().plugins(lock, unlock);

// 遮罩锁屏
function lock(animationMode) {
	if (typeof animationMode == 'undefined') animationMode = false;
	var screen = null;
	if ((screen = $('#screen_lock').getNodes()) != this.info) {
		if (!Base.empty(screen)) {
			Base.removeElement('id = screen_lock');
			screen = Base.addElement('div', 'id = screen_lock', null, document.body);
		};
	} else {
		screen = Base.addElement('div', 'id = screen_lock', null, document.body);
	}
	Base.absolute(screen);
	var scroll = Base.scroll();
	$(document.documentElement).css('overflow', 'hidden');
	var windowRectangle = Base.getWindowRectangle();
	Base.scroll(scroll.x, scroll.y);
	$(screen).css([
								'color : green',
								'zIndex : 9998',
								'top : ' + scroll.y + 'px',
								'left : ' + scroll.x + 'px',
								'width : ' + windowRectangle.width + 'px', 
								'height : ' + windowRectangle.height + 'px', 
								'background-color : black'
						]).show();
	if (!!animationMode) {
		$(screen).animation({
			action : 'o',
			start : 0,
			target : 40,
			isBuffer : true,
			speed : 10
		});
	} else {
		$(screen).css(['opacity : 0.4', 'filter : alpha(opacity = 40)']);
	}
	Base.fixed(screen);
	return this;
}

// 清除锁屏
function unlock(animationMode) {
	if (typeof animationMode == 'undefined') animationMode = false;
	var screen = null;
	if (!(screen = $('#screen_lock').getNodes()) != this.info && Base.empty(screen)) {
		if (!!animationMode) {
			$(screen).animation({
				action : 'o',
				target : 0,
				isBuffer : true,
				speed : 10,
				method : close
			});
		} else {
			close();
		}
	}
	function close() {
		$(screen).hide();
		var scroll = Base.scroll();
		$(document.documentElement).css('overflow', 'auto');
		Base.scroll(scroll.x, scroll.y);
	}
	return this;
}

 

/*
	源码作者: 石不易(Louis Shi)
	联系方式: http://www.shibuyi.net
	===================================================================================
	插件: 元素拖拽
*/

$().plugins(drag);

// 元素拖拽
function drag(selector) {
	var elementNode = null, targetNode = null;
	for (var i = 0; i < this.elements.length; i ++) {
		elementNode = this.elements[i];
		if (typeof selector == 'string') { // 拖拽子节点
			if ((targetNode = $(elementNode).selector(selector).getNodes()) == this.info) continue;
		} else { // 拖拽自身
			targetNode = elementNode;
		}
		if (targetNode instanceof Array) { // 集群
			for (var j = 0; j < targetNode.length; j ++) {
				$(targetNode[j]).css('cursor', 'move').nodeEvent('mousedown', down);
			}
		} else { // 单一
			$(targetNode).css('cursor', 'move').nodeEvent('mousedown', down);
		}
		Base.fixed(elementNode);
	}
	function down(event) {
		Base.absolute(elementNode);
		if (Base.empty(elementNode)) event.preventDefault(); // Firefox Bug
		Tool.setCaptureIE(elementNode);
		var outerRectangle = Base.getOuterRectangle(elementNode);
		var windowRectangle = Base.getWindowRectangle();
		var innerRectangle = Base.getInnerRectangle(elementNode);
		var scroll = Base.scroll();
		var fixedX = event.clientX - outerRectangle.left;
		var fixedY = event.clientY - outerRectangle.top;
		var minX = scroll.x;
		var minY = scroll.y;
		var maxX = (windowRectangle.width - innerRectangle.width) + scroll.x;
		var maxY = (windowRectangle.height - innerRectangle.height) + scroll.y;
		$(document).nodeEvent('mousemove', move);
		$(document).nodeEvent('mouseup', up);
		function move(event) {
			var x = event.clientX - fixedX;
			var y = event.clientY - fixedY;
			if (x < minX) x = minX;
			if (x > maxX) x = maxX;
			if (y < minY) y = minY;
			if (y > maxY) y = maxY;
			$(elementNode).css(['left : ' + x + 'px', 'top : ' + y + 'px']);
		}
		function up() {
			Tool.releaseCaptureIE(elementNode);
			$(this).nodeEvent('mousemove', move, false);
			$(this).nodeEvent('mouseup', up, false);
		}
	}
	return this;
}

 

/*
	源码作者: 石不易(Louis Shi)
	联系方式: http://www.shibuyi.net
	===================================================================================
	插件: 禁止元素溢出可视区
*/

$().plugins(overflow);

// 禁止元素溢出
function overflow() {
	var scroll = Base.scroll();
	var windowRectangle = Base.getWindowRectangle();
	var outerRectangle = null, innerRectangle = null, elementNode = null;
	var minX = scroll.x, minY = scroll.y, maxX = 0, maxY = 0, x = 0, y = 0;
	for (var i = 0; i < this.elements.length; i ++) {
		elementNode = this.elements[i];
		Base.absolute(elementNode);
		outerRectangle = Base.getOuterRectangle(elementNode);
		innerRectangle = Base.getInnerRectangle(elementNode);
		x = outerRectangle.left;
		y = outerRectangle.top;
		maxX = (scroll.x + windowRectangle.width) - innerRectangle.width;
		maxY = (scroll.y + windowRectangle.height) - innerRectangle.height;
		if (x < minX) x = minX;
		if (x > maxX) x = maxX;
		if (y < minY) y = minY;
		if (y > maxY) y = maxY;
		$(elementNode).css(['left : ' + x + 'px', 'top : ' + y + 'px']);
	}
	return this;
}

 

/*
	源码作者: 石不易(Louis Shi)
	联系方式: http://www.shibuyi.net
	===================================================================================
	插件: 元素动画
*/

$().plugins(animation);

// 元素动画
function animation(animation) {
	var elementNode = null, animationList = [];
	for (var i = 0; i < this.elements.length; i ++) {
		elementNode = this.elements[i];
		if (i == 0 && !(animation = Base.checkAnimation(animation, elementNode))) {
			return this;
		}
		var unique = '';
		for (var j = 0; j < animation.action.length; j ++) {
			// 组合唯一标识符(用于定时器)
			unique += animation.action[j];
			if (animation.action[j] == 'opacity') {
				$(elementNode).css('opacity', animation.start[j] / 100);
				$(elementNode).css('filter', 'alpha(opacity=' + animation.start[j] + ')');
			} else {
				// 设置初始值
				$(elementNode).css(animation.action[j], animation.start[j] + 'px');
			}
		}
		// 清除动画唯一标识
		if (typeof elementNode[unique] == 'number') clearTimeout(elementNode[unique]);
		
		(function (elementNode) { // 警告: IE 6/7/8 出现多定时器, 多重触发动画时, 会严重卡顿
				// 定时器
				elementNode[unique] = setTimeout(function () {
					clearTimeout(elementNode[unique]);
					var value = 0, target = 0, step = 0, action = '', flags = [];
					for (var i = 0; i < animation.action.length; i ++) {
						// 动画动作
						action = animation.action[i];
						// 目标量
						target = animation.target[i];
						// 步长量
						step = animation.step[i];
						
						if (action == 'opacity') {
							if (browserDetect.ie && browserDetect.browser.version < 9) {
								var opacity = Base.trim($(elementNode).css('filter'));
								value = Base.number(/alpha\(opacity([\s\t ]*)=\1(\d+)\)/i.exec(opacity)[2]);
							} else {
								value = $(elementNode).css('opacity') * 100;
							}
						} else {
							// 获取当前值
							value = parseInt(Base.replace($(elementNode).css(action), 'px'));
						}
						
						// 缓冲处理
						if (animation.isBuffer) {
							var speed = (target - value) / animation.speed;
							step = step > 0 ? Math.ceil(speed) : Math.floor(speed);
						}
						
						if (target == value || step == 0) continue;
						
						// 检测动画当前值
						if (step > 0 && Math.abs(target - value) <= step) { // 结束(递增)
							setAnimation(target);
							flags[i] = false;
						} else if (step < 0 && Math.abs(value - target) <= Math.abs(step)) { // 结束(递减)
							setAnimation(target);
							flags[i] = false;
						} else { // 继续执行动画
							setAnimation(value + step);
							flags[i] = true;
						}
					}
					
					// 执行动画
					function setAnimation(value) {
						if (action == 'opacity') {
							$(elementNode).css('opacity', Base.number(value) / 100);
							$(elementNode).css('filter', 'alpha(opacity=' + Base.number(value) + ')');
						} else {
							$(elementNode).css(action, Base.number(value) + 'px');
						}
					}
					
					// 遍历动画开关
					for (var k = 0; k < flags.length; k ++) {
						if (flags[k]) {
							flags = true;
							break;
						}
					}
					
					if (flags === true) { // 继续执行
						elementNode[unique] = setTimeout(arguments.callee, animation.time);
					} else { // 执行列队
						animation.method();
					}
				}, animation.time);
			})(elementNode);
	}
	return this;
}

 

/*
	源码作者: 石不易(Louis Shi)
	联系方式: http://www.shibuyi.net
	===================================================================================
	插件: 事件切换器
*/

$().plugins(toggle);

// 事件切换器
function toggle() {
	var methodList = arguments;
	if (methodList.length != 0) {
		var elementNode = null;
		for (var i = 0; i < this.elements.length; i ++) {
			elementNode = this.elements[i];
			// 闭包实现计数器唯一性
			(function () {
				var counter = 0;
				$(elementNode).nodeEvent('click', function () {
					methodList[counter ++].call(this);
					if (counter >= methodList.length) counter = 0;
				});
			})();
		}
	}
	return this;
}

 

关于 BETA 4.0 测试版核心源码与实例演示的获取请移动至官网下载!

 

感谢大家积极评测给予意见!

 

官网地址:http://www.shibuyi.net

 

CNBlogs 博客:http://www.cnblogs.com/shibuyi/

 

CSDN 博客:http://blog.csdn.net/louis_shi/

 

ITeye 博客:http://shibuyi.iteye.com/

 

 

1
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics