Greasy Fork

TQuery

我的仿jq库

目前为 2015-07-23 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.greasyfork.cloud/scripts/11045/63721/TQuery.js

// ==UserScript==
// @name	TQuery
// @author	burningall
// @description	我的仿jq库
// @version     2015.7.18
// @run-at	document-start
// @compatible  chrome  
// @compatible  firefox  
// @license     The MIT License (MIT); http://opensource.org/licenses/MIT
// @supportURL		http://www.burningall.com
// @contributionURL	[email protected]|alipay.com
// @namespace https://greasyfork.org/zh-CN/users/3400-axetroy
// ==/UserScript==


(function(window,document){//自调用,避免全局污染
//========构造函数========
function TQuery(tArg){
	this.arg = tArg;//保存传进来的参数
	this.elements = [];//用来保存选择的元素
	this.doc = document;
	switch( typeof tArg ){
		case "function" :
			addEvent(window,'load',tArg);
			break;
		case "string" :
				switch( tArg.charAt(0) ){
					case '<' :	//<div></div>,创建元素
						var tagName = tArg.match(/^\<[a-z]+\>/ig)[0].match(/[a-z]+/ig)[0];			//标签名
						var tagContent = tArg.match( /\>[\s\S]*\</ )[0];		
						var content = tagContent.substring(1,tagContent.length-1);					//标签内容
						var newElement = this.doc.createElement(tagName);
						newElement.innerHTML = content;
						this.elements.push(newElement);
						break;
					default:	//默认情况下是选择符
						if(this.doc.querySelectorAll){//现代浏览器
							var aElems = this.doc.querySelectorAll(tArg);
							for(var i=0;i<aElems.length;i++){
								this.elements.push(aElems[i])
							}
						}else if( !this.doc.querySelectorAll ){
							alert( '您的浏览器版本太低,请升级至IE8或以上,或者使用chrome,firefox,opera等现代浏览器' );
						}
						/*
						//让IE8以下去死,不兼容了
						else{//通用,兼容到IE5-11,firefox,chrome…………
								var elements = tArg.split(/\s+/ig);	//拆分节点,并且保持进数组[ul,li,a]
								var childElements = [];			//创建一个临时数组
								var parentNode = [];			//用来存放父节点
								for(var i=0;i<elements.length;i++){
									switch( elements[i].charAt(0) ){
										case "#" ://ID
											childElements = [];//清理临时节点,以便父节点失效,子节点有效
											childElements.push( document.getElementById(elements[i].substring(1)) );
											parentNode = childElements;	//保存父节点,因为childElements需要清理,所以需要创建node储存。
											break;
										case "." ://class
											childElements = [];//清理临时节点,以便父节点失效,子节点有效
											//输出父节点,如果开头为  '.ul li'
											if(parentNode=='' || parentNode == null){
												var aElement = getByClass(document,elements[0].substring(1));
												for(var y=0;y<aElement.length;y++){
													parentNode.push( aElement[y] );
												}
												childElements = parentNode;
												break;
											}
											//输出子集节点
											for(var j=0;j<parentNode.length;j++){
												var temps =[];		//创建一个临时数组,用于储存子集元素
												var aElement = getByClass(parentNode[j],elements[i].substring(1));
												for(var x=0;x<aElement.length;x++){
													temps.push( aElement[x] );
												}
												for(var k=0;k<temps.length;k++){
													childElements.push( temps[k] );
												}
											}
											break;
										default : //tagName
											childElements = [];//清理临时节点,以便父节点失效,子节点有效
											//输出父节点,如果开头为  'ul li'
											if(parentNode=='' || parentNode == null){
												var aElement = document.getElementsByTagName(elements[0]);
												for(var y =0;y<aElement.length;y++){
													parentNode.push( aElement[y] );
												}
												childElements = parentNode;
												break;
											}
											//输出子集节点
											for(var j=0;j<parentNode.length;j++){
												var temps =[];		//创建一个临时数组,用于储存子集元素
												var aElement = parentNode[j].getElementsByTagName(elements[i]);//获取伙计下的所有子集元素
												for(var x=0;x<aElement.length;x++){
													temps.push( aElement[x] );
												}
												for(var k=0;k<temps.length;k++){
													childElements.push( temps[k] )
												}
											}
									}//switch
								}//for
								this.elements = childElements;
						}
						*/
					break;
				}
			break;
		case "object" : //对象
			this.elements.push(tArg);
			break;
	}
	this.length = this.elements.length;
}
//========链式操作方法========
//eq根据下标选择
TQuery.prototype.eq = function(n){
	var n = n || 0;
	this.length = 1;
	return $(this.elements[n]);//作为对象存进this.elements,以便链式结构
}
//filter过滤器,只能过滤子代元素
TQuery.prototype.filter = function(str){
	var childElements = [];//存放临时数据
	for(var i=0;i<this.length;i++){
		switch( str.charAt(0) ){
			case '#':	//id
				if( $(this.elements[i]).attr('id') != str.substring(1) ){
					childElements.push( this.elements[i] );
				}
				break;
			case '.':	//class
				if( !this.hasClass(this.elements[i],str.substring(1)) ){//没有匹配到class
					childElements.push( this.elements[i] );
				}
				break;
			default :	//tagName
				if( this.elements[i].tagName != str.toUpperCase() ){
					childElements.push( this.elements[i] );
				}
		}//swicth
		/*
		if(this.doc.querySelectorAll){//现代浏览器
			var aElems = this.elements[i].querySelectorAll(':not(' + str +')');
			var length = aElems.length;
			var j =0;
			while(j<length){
				childElements.push( aElems[j] );
				j++
			}
		}else if( !this.doc.querySelectorAll ){
			alert( '您的浏览器版本太低,请升级至IE8或以上,或者使用chrome,firefox,opera等现代浏览器' );
		}
		*/
		/*
		//让IE8以下去死,不兼容了
		else{//通用
			var aElems =this.elements[i].getElementsByTagName('*');//获得所有子节点
			var length = aElems.length;
			switch( str.charAt(0) ){
				case '#' : 	//#div1
					for(var j=0;j<length;j++){
						if( $(aElems[j]).attr('id') !== str.substring(1) ){
							childElements.push(aElems[j]);
						}
					}
					break;
				case '.' :	//.class
					for(var j=0;j<length;j++){
						if( $().hasClass( aElems[j],str.substring(1) ) == false ){
							childElements.push(aElems[j]);
						}
					}
					break;
				default :	//tagName
					for(var j=0;j<length;j++){
						if(aElems[j].tagName.toLowerCase() != str ){
							childElements.push(aElems[j]);	
						}
					}//for
			}//switch
		}
		*/
	}//for
	//console.log(childElements  )
	this.elements = childElements;
	this.length = childElements.length;//返回新的长度
	return this;
}
//find选择
TQuery.prototype.find = function(str){
	var childElements = [];//存放临时数据
	for(var i=0;i<this.length;i++){
		if(document.querySelectorAll){//现代浏览器
			var aElems = this.elements[i].querySelectorAll(str);
			var length = aElems.length;
			var j =0;
			while(j<length){
				childElements.push( aElems[j] );
				j++
			}
		}else{//通用
			switch( str.charAt(0) ){
				case '#' : 	//#div1
					var aElems = this.elements[i].getElementById(str.substring(1));
					childElements.push( aElems );
					break;
				case '.' :	//.class
					var aElems= getByClass( this.elements[i],str.substring(1) );
					childElements = childElements.concat(aElems);
					break;
				default :	//tagName
					var aElems = this.elements[i].getElementsByTagName(str);
					var length = aElems.length;
					for(var j=0;j<length;j++){
						childElements.push( aElems[j] );
					}
					//aResult = aResult.concat(aElems);会出问题,数组不能与集合
			}
		}
	}
	this.elements = childElements;
	this.length = childElements.length;//返回新的长度
	return this;
}
//add,将元素添加到已有的合集
TQuery.prototype.add = function(str){
	var newTQ = $(str);
	var newTQLength = newTQ.length;
	var temps = this.elements;
	for(var i=0;i<newTQLength;i++){
		temps.push( newTQ.elements[i] );
	}
	//this.elements = temps.unique();//重复的DOM节点去重
	this.elements = temps;
	this.length = this.elements.length;//生成新的长度
	return this;//返回对象
}
//each循环遍历
TQuery.prototype.each = function(fn){
	for(var i=0;i<this.length;i++){
		var _this = this.elements[i];
		fn.call(_this);
	}
	return this;//返回对象
}
//click事件
TQuery.prototype.click = function(fn){
	var length = this.elements.length;
	for(var i=0;i<length;i++){
		addEvent(this.elements[i],'click',fn);
	}
	return this;//返回对象,进行链式操作
}
//获取DOM/window/document的width/height
TQuery.prototype.width = function(setting){
	if(this.elements[0] instanceof Object && (this.elements[0].alert || this.elements[0].body) ){//如果是window,或document
		return this.doc.body.scrollWidth> this.doc.documentElement.scrollWidth ? this.doc.body.scrollWidth : this.doc.documentElement.scrollWidth;//获取带padding和margin的值
	}else if(setting){//设置宽度
		this.css('width',setting);
		return this;//返回对象,进行链式操作
	}else{
		return parseInt( this.style('width'));//读取
	}
}
TQuery.prototype.height = function(setting){
	if(this.elements[0] instanceof Object && (this.elements[0].alert || this.elements[0].body) ){//如果是window,或document,则返回整个文档高度
		return this.doc.body.scrollHeight>this.doc.documentElement.scrollHeight ? this.doc.body.clientHeight : this.doc.documentElement.scrollHeight;//获取带padding和margin的值
	}else if(setting){//设置高度
		this.css('height',setting);
		return this;//返回对象,进行链式操作
	}else if(!setting){
		return parseInt( this.style('height') );//获取高度
		}
}
//获取可视区域宽高
TQuery.prototype.viewWidth = function(){
	return this.doc.body.clientWidth<this.doc.documentElement.clientWidth ? this.doc.body.clientWidth : this.doc.documentElement.clientWidth;//取较小值
}
TQuery.prototype.viewHeight = function(){
	return this.doc.body.clientHeight<this.doc.documentElement.clientHeight ? this.doc.body.clientHeight : this.doc.documentElement.clientHeight;//取较小值
}
//获取DOM的top/left
TQuery.prototype.top = function(setting){
	if(setting){
		this.css('top',setting);
		return this;//返回对象,进行链式操作
	}
	return parseInt( this.elements[0].offsetTop );
}
TQuery.prototype.left = function(setting){
	if(setting){
		this.css('left',setting);
		return this;//返回对象,进行链式操作
	}
	return parseInt( this.elements[0].offsetLeft );
}
//鼠标滚轮滚动
/*
IE			attachEvent				mousewheel				wheelDelta		滚轮下e.wheelDelta<0
firefox		addEventListener		DOMMouseScroll			detail			滚轮下e.detail>0
chrome		addEventListener		mousewheel				wheelDelta		滚轮下e.wheelDelta<0
*/

TQuery.prototype.mouseScroll = function(json){
	this.bind('mousewheel DOMMouseScroll',function(e){
		if(e.wheelDelta){//chrome,ie
			if( e.wheelDelta > 0 ){//滚轮向下滚动
				json.up.call(this,e);
			}else{
				json.down.call(this,e);
			}
		}else{//狗日的firefox
			if(e.detail<0){//鼠标滚轮按下
				json.up.call(this,e);	
			}else{
				json.down.call(this,e);
			}
		}
	})
	return this;//返回对象,进行链式操作
}

//scroll到某一位置,或获取滚动条位置
TQuery.prototype.scrollTop = function(target,endFn){
	if(target!=0 && !target){//没有参数,则读取
		var scrollTop = this.doc.body.scrollTop || this.doc.documentElement.scrollTop;
		return scrollTop;
	}
	var _this = this;
	clearInterval(this.doc.timerScroll);
	this.doc.timerScroll = setInterval(function(){
		var nowScrollTop = _this.doc.body.scrollTop || _this.doc.documentElement.scrollTop;
		var dif = Math.abs(nowScrollTop-target);	//目前与目标的差值
		var speed = (dif/10)+10;	//滚动速度
		if(nowScrollTop-target<0){//向下滚
			speed = speed;
		}else{//向上滚动
			speed = - speed;
		}
		var position = nowScrollTop + (speed);	//生成计算后的位置
		if( (speed>0 && position>=target) || (speed<0 && position<=target) ){//如果到达目标点
			_this.doc.body.scrollTop = _this.doc.documentElement.scrollTop = target;
			endFn && endFn.call(_this);	//防止this冲突,此处this指的是TQuery对象
			clearInterval(_this.doc.timerScroll);
		}
		_this.doc.body.scrollTop = _this.doc.documentElement.scrollTop = position;
	},20)
	return this;//返回对象,进行链式操作
}
//scroll到顶部或底部
TQuery.prototype.scroll = function(dir,step,endFn) { //obj随意,dir>0往上滚,dir<0往下滚
	var step = step || 10;
	clearInterval(this.doc.timerScroll);
	var _this = this;
	this.doc.timerScroll = setInterval(function() {
		var position;
		if (dir == 'up') { //往上滚动
			var speed = ($(this).size('scrollTop') / step) + 1;
			position = $(this).size('scrollTop') - speed;
			if (position <= 0) { //如果滚到顶部
				_this.doc.body.scrollTop = _this.doc.documentElement.scrollTop = 0;
				endFn && endFn();
				clearInterval(_this.doc.timerScroll);
			}
		}else if(dir == 'down'){ //往下滚动
			var speed = (($(this).size('scrollHeight') - $(this).size('scrollTop') - $(this).size('clientHeight')) / step) + 1;
			position = $(this).size('scrollTop') + speed;
			if (position + $(this).size('clientHeight') >= $(this).size('scrollHeight')) { //如果滚到底部
				_this.doc.body.scrollTop = _this.doc.documentElement.scrollTop = $(this).size('scrollHeight');
				endFn && endFn();
				clearInterval(_this.doc.timerScroll);
			}
		}
		_this.doc.body.scrollTop = _this.doc.documentElement.scrollTop = position;
	}, 20)
	return this;//返回对象,进行链式操作
}
//事件的绑定与删除
TQuery.prototype.bind = function(type,fn){
	if(arguments.length==1){//如果只传一个json参数e
		for(var i=0;i<this.length;i++){
			for(var attr in type){
				addEvent(this.elements[i],attr,type[attr]);
			}
		}
	}else{//如果传两个参数,则统一执行一个e
		var events = type.split(' ');
		var eventsLength = events.length;
		for(var i=0;i<this.length;i++){
			var j=0;
			while(j<eventsLength){
				addEvent(this.elements[i],events[j],fn);
				j++;
			}
		}
	}
	return this;//返回对象,进行链式操作
}
//解除事件绑定,匿名函数无法解除绑定
TQuery.prototype.unbind = function(e,fn){
	for(var i=0;i<this.length;i++){
		removeEvent(this.elements[i],e,fn);
	}
	return this;//返回对象,进行链式操作
}
//类似onload,onmouseover等
TQuery.prototype.on = function(type,fn){
	if(arguments.length==1){//如果只传一个json参数
		for(var i=0;i<this.length;i++){
			for(var attr in type){
				this.elements[i][ 'on'+attr ] = type[attr];
			}
		}
	}else{//如果传两个参数e,fn
		var events = type.split(' ');//获取每个事件
		var eventsLength = events.length;
		for(var i=0;i<this.length;i++){
			var j =0;
			while(j<eventsLength){
				this.elements[i][ 'on'+events[j] ] = fn;
				j++;
			}
		}
	}
	return this;//返回对象,进行链式操作
}
//one执行一次操作
TQuery.prototype.one = function(e,fn){
	var _this = this;
	for(var i=0;i<this.length;i++){
		this.on(e,function(){
			fn.call(_this);//解决匿名函数this指针不正确的问题
			var es = e.split(' ');
			var j=0;
			while(j<es.length){
				this['on'+es[j]] = null;
				j++;
			}
		})
	}
	return this;//返回对象,进行链式操作
}
//show
TQuery.prototype.show = function(){
	for(var i=0;i<this.length;i++){
		this.elements[i].style.display = 'block';
	}
	return this;//返回对象,进行链式操作
}
//hide
TQuery.prototype.hide = function(){
	for(var i=0;i<this.length;i++){
		this.elements[i].style.display = 'none';
	}
	return this;//返回对象,进行链式操作
}
//设置hover
TQuery.prototype.hover = function(over,out){
	for(var i=0;i<this.length;i++){
		addEvent(this.elements[i],'mouseover',over);
		addEvent(this.elements[i],'mouseout',out);
	}
	return this;//返回对象,进行链式操作
}
//设置css
//$('').css('width',value)	//value>>>200||200px||20%,json要带格式px
TQuery.prototype.css = function(attr,value){
	var type = /width|height|left|top|bottom|right|margin|padding/ig;
	if(arguments.length==2){//设置样式
		if( type.test(attr) && value.indexOf('%')<0 ){
			value = parseInt(value) + 'px';
		}
		for(var i=0;i<this.length;i++){
			this.elements[i].style[attr] = value;
		}
	}else{//一个参数
		if(typeof attr=="string"){//获取样式
			return this.elements[0].currentStyle ? this.elements[0].currentStyle[attr] : getComputedStyle(this.elements[0])[attr];
		}else if( typeof(attr) == "object" && Object.prototype.toString.call(attr).toLowerCase() == "[object object]" && !attr.length ){//json
			for(var i =0;i<this.length;i++){
				for(var k in attr){
					if(type.test(attr[k]) && attr[k].indexOf('%')<0 ){
						attr[k] = parseInt(attr[k]) + 'px';
					}
					this.elements[i].style[k] = attr[k];
				}
			}
		}
		
	}
	return this;//返回对象,进行链式操作
}
//设置动画
TQuery.prototype.animate = function(json,loadFn,endFn){
	for(var i=0;i<this.length;i++){
		var _this = this.elements[i];
		clearInterval(_this.animate);
		_this.animate = setInterval(function() {
			//注意,此处this指的是window(匿名函数)
			var bStop = true;//判断运动是否停止
			for(attr in json){//attr代表属性,'width','height'.而json[attr]代表数值
				// 1. 取得当前的值(可以是width,height,opacity等的值)
				var objAttr = 0 ;
				if(attr == 'opacity'){//获取当前数值
					objAttr = Math.round(parseFloat( $(_this).style(attr) ) * 100);
				}else{
					objAttr = parseInt( $(_this).style(attr) );
				}
				// 2.计算运动速度
				var iSpeed = (json[attr] - objAttr) / 10;	//(目标数值-当前数值)/10
				iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);	//如果速度>0,则速度向上取整,如果小于0,则保留小数
				// 3. 检测所有运动是否到达目标
				/*
				if (objAttr != json[attr]) {//如果当前值不等于目标值
					bStop = false;
				}
				*/
				//objAttr,当前点,json[attr]为目标点
				if ( (iSpeed>0 && objAttr <= json[attr]) || (iSpeed<0 && objAttr >= json[attr]) ) {//如果有其中一项没有达到目标
					bStop = false;
				}
				if (attr == "opacity") {
					_this.style.filter = 'alpha(opacity:' + (objAttr + iSpeed) + ')';
					_this.style.opacity = (objAttr + iSpeed) / 100;
				} else {
					_this.style[attr] = objAttr + iSpeed + 'px'; // 需要又.属性名的形式改成[]
				}
				loadFn && loadFn.call(_this);//每次都执行
				if (bStop) { // 表示所有运动都到达目标值
					clearInterval(_this.animate);
					endFn && endFn.call(_this);//传入参数,防止当前this错误
				}
			}//for
		},30)
	}//for
	return this;//返回对象,进行链式操作
}
//停止动画
TQuery.prototype.stop = function(delay){
	var delay = delay ? delay : 0;
	setTimeout(function(){
		clearInterval( $(this).elements[0].animate );
	},delay)
	return this;//返回对象,进行链式操作
}
//设置拖拽
TQuery.prototype.drag = function(json){
	for(var i=0;i<this.length;i++){
		new Drag( this.elements[i],this.elements[i],json )
	}
	return this;
}
//设置attr
TQuery.prototype.attr = function(attr,value){
	if(arguments.length==2){//2个参数,设置属性
		for(var i=0;i<this.length;i++){
			this.elements[i][attr] = value;
		}
	}else if(arguments.length==1){//1个参数
		if( typeof(attr) == "object" && Object.prototype.toString.call(attr).toLowerCase() == "[object object]" && !attr.length ){//如果是json,则分别设置属性
			for(var i=0;i<this.length;i++){
				for(var j in attr){
					this.elements[i][j] = attr[j];
				}
			}
		}else{//读取属性
			return this.elements[0][attr];	
		}
	}
	return this;//返回对象,进行链式操作
}
//设置自定义属性
TQuery.prototype.custormAttr = function(attr,value){
	if(arguments.length==2){//两个参数,设置属性
		for(var i=0;i<this.length;i++){
			this.elements[i].setAttribute(attr,value);
		}
	}else if(arguments.length==1){//1个参数
		if( typeof(attr) == "object" && Object.prototype.toString.call(attr).toLowerCase() == "[object object]" && !attr.length ){//json格式,则分别设置
			for(var i=0;i<this.length;i++){
				for(var j in attr){
					this.elements[i].setAttribute(j,attr[j]);
				}
			}
		}else{//读取属性
			return this.elements[0].getAttribute(attr);
		}
	}
	return this;//返回对象,进行链式操作
}
//点击开关toggle
TQuery.prototype.toggle = function(){
	var _arguments = arguments;
	var	length = _arguments.length;
	var count = 0;
	for(var i=0;i<this.length;i++){
		var _this = this.elements[i];
		this.on('click',function(){
			_arguments[count++%length].call(_this);//执行	,解决this错误的问题
		})
	}
	return this;//返回对象,进行链式操作
}
//设置innerHTML
TQuery.prototype.html = function(setting){
	if(setting){//设置
		for(var i=0;i<this.length;i++){
			this.elements[i].innerHTML = setting;
		}
		return this;
	}
	return this.elements[0].innerHTML;
}
//设置text
TQuery.prototype.text = function(setting){
	if(setting){//设置
		for(var i=0;i<this.length;i++){
			this.elements[i].innerText = this.elements[i].textContent = setting;
		}
		return this;
	}
	return this.elements[0].innerText || this.elements[0].textContent;
}
//get,将TQuery对象转换成DOM对象,多个则返回数组
TQuery.prototype.get = function(n){
	n = n || 0;
	if(n=='all' && this.length>1){//如果没有参数,并且多个,则返回数组
		return this.elements;
	}
	return this.elements[n];
}
//添加class
TQuery.prototype.addClass = function(cName){
	for(var i=0;i<this.length;i++){
		if (!this.hasClass(this.elements[i],cName)) {//如果不存在class
			if( this.elements[i].className == null || this.elements[i].className == '' ){
				this.elements[i].className = cName;
			}else{
				this.elements[i].className += " " + cName;
				if(this.elements[i].className){
					
				}
			};
		};
	};
	return this;//返回对象,进行链式操作
}
//移除class
TQuery.prototype.removeClass = function(cName){
	for(var i=0;i<this.length;i++){
		if (this.hasClass(this.elements[i],cName)) {
			this.elements[i].className = this.elements[i].className.replace(new RegExp("(\\s|^)" + cName + "(\\s|$)"), ""); // replace方法是替换 
		};
	}
	return this;//返回对象,进行链式操作
}
//插入after,把选择到的元素,插入到obj的后面
TQuery.prototype.insertAfter = function(obj){
	var parent;
	for(var i=0;i<this.length;i++){
		parent = obj.parentNode;//插入位置的父元素
		if(parent.lastChild == obj){//如果最后的节点是目标节点,直接添加
			parent.appendChild(this.elements[i]);
		}else{//如果不是,则插入在目标元素的下一个兄弟节点的前面,也就是目标元素的后面
			parent.insertBefore(this.elements[i],obj.nextSibling);	
		}
	}
	return this;//返回对象,进行链式操作
}
//插入insertBefore,把选择到的元素,插入到obj的前面
TQuery.prototype.insertBefore =function(obj){
	for(var i=0;i<this.length;i++){
		obj.parentNode.insertBefore(this.elements[i],obj);
	}
	return this;//返回对象,进行链式操作
}
//清空选中节点,但不删除
TQuery.prototype.empty = function(){
	for(var i=0;i<this.length;i++){
		this.html(' ');
	}
	return this;//返回对象,进行链式操作
}
//删除选中节点
TQuery.prototype.remove = function(){
	for(var i=0;i<this.length;i++){
		this.elements[i].remove();
	}
	return this;//返回对象,进行链式操作
}
//========非链式操作方法========
//返回当前节点的index值
TQuery.prototype.index = function(){
	var index = 0;
	var aBrother = this.elements[0].parentNode.children;//获取兄弟节点
	var length = aBrother.length;
	for(var i=0;i<length;i++){//遍历
		if( aBrother[i] == this.elements[0] ){//如果匹配到
			index = i;
			break;
		}
	}
	return index;
}
//当回所选元素[0]的父节点
TQuery.prototype.parent = function(){
	var temps = [];
	temps.push( this.elements[0].parentNode );
	this.elements = temps;
	return this;
}
//返回每个所选元素的所有父节点
//未完成
TQuery.prototype.parents = function(){
	var temps = [];//存储所有的父节点
	for(var i=0;i<this.length;i++){
		temps.push( this.elements[i].parentNode );
	}
	this.elements = temps;
	return this;
}
//Mutation Observer,DOM变动观察器,异步触发的
//未完成
TQuery.prototype.matation = function(options){
	//new MutationObserver(callback)
	var observer = new MutationObserver(function(record){
		for(var n,i=0;i<record.length;i++){
			 console.log(record[i].target);
			}
		})
	var options = {
		'childList': true,
		'arrtibutes': true
	};
	observer.observe(this.elements[i],options);
}
//hasClass
TQuery.prototype.hasClass = function(obj,cName){
	// ( \\s|^ ) 判断前面是否有空格 (\\s | $ )判断后面是否有空格 两个感叹号为转换为布尔值 以方便做判断
	return !! obj.className.match(new RegExp("(\\s|^)" + cName + "(\\s|$)"));
}
//返回计算后的style样式
TQuery.prototype.style = function(attr){
	return this.elements[0].currentStyle ? this.elements[0].currentStyle[attr] : getComputedStyle(this.elements[0])[attr];
}
//返回个BOM的尺寸
TQuery.prototype.size = function(attr){
	return this.doc.documentElement[attr] ? this.doc.documentElement[attr] : this.doc.body[attr]
}
//AJAX
TQuery.prototype.ajax = function(url,SucessFn,FaildFn){
	/*
		1,实例化对XMLHttpRequese对象
		2,ajax对象的open方法服务器
		3,ajax对象的send方法,发送请求
		4,监听onreadystatechange变化
			0,readyState,请求初始化,open方法没有被调用
			1,与服务器连接,open已调用
			2,请求已接收,(服务器收到请求的头部信息)
			3,请求处理中,(服务器收到请求的主体内容)
			4,响应完成,并且返回数据
				返回值有ajax.responseText和ajax.responseXML
	*/
	var oAjax;
	if(window.XMLHttpRequest){//IE7+,chrome,firefox,opara,safari
		oAjax=new XMLHttpRequest();
	}else{//兼容非IE6
		oAjax=new ActiveXObject("Microsoft.XMLHTTP");//IE5,IE6
	};
	oAjax.open('GET',url,true);//true为异步,false为同步
	oAjax.send();//post请求就需要填写参数string
	oAjax.onreadystatechange=function(){
		if(oAjax.readyState==4){	//响应完成
			if(oAjax.status==200){//状态码=200,请求成功
				SucessFn(oAjax.responseText);//传参返回值
			}else{//读取失败
					FaildFn && FaildFn(oAjax.status);
			};
		};
	};
};
//扩展插件
TQuery.prototype.extend = function(name,fn){
	TQuery.prototype[name] = fn;
	return this;//返回对象,进行链式操作
}
//输出调用
function $(tArg){
	return new TQuery(tArg);
}
window.$ = window.TQuery = $;
//========通用函数========
function addEvent(obj, type, fn){
	return obj.addEventListener ? 
			obj.addEventListener(type, function(e){
				var ev = window.event ? window.event : (e ? e : null);
				ev.target = ev.target || ev.srcElement;
				if( fn.call(obj,ev)==false ){//回掉函数为false,则阻止默认时间
					e.cancelBubble = true;//阻止冒泡
					e.preventDefault();//chrome,firefox下阻止默认事件
				}
			}, false)
			 : 
			obj.attachEvent('on' + type, function(e){
				//fn.call(obj,e);//解决IE8下,this是window的问题
				var ev = window.event ? window.event : (e ? e : null);
				ev.target = ev.target || ev.srcElement;
				if(fn.call(obj,ev)==false ){
					e.cancelBubble = true;//阻止冒泡
					return false;//阻止默认事件,针对IE8
				}
			});
}
function removeEvent(obj,type,fn){
	return obj.removeEventListener ? obj.removeEventListener(type,fn,false) : obj.detachEvent('on' + type,fn);
}
function getByClass(oParent,sClassName){
	var aElement = oParent.getElementsByTagName('*');//获取所有子节点
	var result = [];
	for(var i=0;i<aElement.length;i++){
		if( aElement[i].className == sClassName ){
			result.push(aElement[i]);
		}
	}
	return result;
}
function getByTagName(oParent,sTagName){
	var aElement = oParent.getElementsByTagName(sTagName);//获取所有子节点
	var result = [];
	for(var i=0;i<aElement.length;i++){
		result.push(aElement[i]);
	}
	return result;
}
function startMove(obj, json, loadFn, endFn) {
	obj.timer && clearInterval(obj.timer);
	obj.timer = setInterval(function() {
		var bStop = true;
		for (attr in json) {
			// 1. 取得当前的值(可以是width,height,opacity等的值)
			var objAttr = 0;
			if (attr == "opacity") {
				objAttr = Math.round(parseFloat($(obj).style(attr)) * 100);
			} else {
				objAttr = parseInt( $(obj).style(attr) );
			}
			// 2.计算运动速度
			var iSpeed = (json[attr] - objAttr) / 10;
			iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
			// 3. 检测所有运动是否到达目标
			if (objAttr != json[attr]) {
				bStop = false;
			}
			if (attr == "opacity") {
				obj.style.filter = 'alpha(opacity:' + (objAttr + iSpeed) + ')';
				obj.style.opacity = (objAttr + iSpeed) / 100;
			} else {
				obj.style[attr] = objAttr + iSpeed + 'px'; // 需要又.属性名的形式改成[]
			}
			loadFn && loadFn();//每次都执行
		}
		if (bStop) { // 表示所有运动都到达目标值
			clearInterval(obj.timer);
			endFn && endFn.call(obj);//传入参数,防止当前this错误
		}
	},
	30);
}
//===============系统对象上添加==============
//字符串倒序
String.prototype.reverse = function(){
	return this.split('').reverse().join('')
}
//数组sum求和方法
Array.prototype.sum = function(){
	var result = 0;
	for( var i=0;i<this.length;i++ ){
		result += this[i];
	}
	return result;
}
//数组去重,不能比较DOM节点
Array.prototype.unique = function(){
   var a = {};//哈希表,用来存放不重复的数组
   for (var i=0; i<this.length; i++) {  
	   var v = this[i];
	   if (typeof(a[v]) == 'undefined'){  
			a[v] = 1;  
	   }
   };
   this.length=0;//清空数组
   for (var i in a){//哈希表存放的不重复数据,存入数组中
		this[this.length] = i;  //this.length = 0 , 1 , 2 ……
   }  
   return this;  
}
//删除指定位置的数组,n = (0,n),可以是数字,可以是区间
Array.prototype.del = function(n) {
    if (n < 0) return this;
	if(typeof n == 'object' && n.push()){//如果是数组(区间)
		 return this.slice(0,n[0]).concat( this.slice( n[1]+1 , this.length) );
	}
    return this.slice(0, n).concat( this.slice(n + 1, this.length) );
}
//===============自定义对象==============
//面向对象选项卡
//使用方法 new TabSwitch('div1');
/*
	<div id="div1">
		<input />
		<input />
		<input />
		<div></div>
		<div></div>
		<div></div>
	</div>
结构:
*/
function TabSwitch(obj){
	var _this = this;
	//var div1 = document.getElementById(id);
	var div1 = obj;
	this.aBtn = div1.getElementsByTagName('input');
	this.aDiv = div1.getElementsByTagName('div');
	for(var i=0;i<this.aBtn.length;i++){
		this.aBtn[i].index=i;
		this.aBtn[i].onclick=function(){
			_this.fnClick(this);
			}
	}
};
TabSwitch.prototype.fnClick = function(oBtn){
	for(var j=0;j<this.aBtn.length;j++){
		this.aBtn[j].className='';
		this.aDiv[j].style.display='none';
	}
	oBtn.className='active';
	this.aDiv[oBtn.index].style.display='block';
}
//拖拽
//使用方法 new Drag($('press'),$('move'),{left:[100,200],top:[200,500]});(鼠标按住的目标,要移动的目标)
/*
var json = {
			L:[100,300],
			T:[200,500]
			}
*/
function Drag(pressTarget,MoveTarget,json){
	var _this = this;
	this.disX = 0;
	this.disY = 0;
	if(json){
		this.json = json;
	}
	this.MoveTarget = MoveTarget;
	pressTarget.onmousedown = function(e){
		_this.fnDown(e);
		return false;//chrome,firefox去除文字选中
	};
}
Drag.prototype.fnDown = function(e){//鼠标按下(未松开)
	var e = e || window.event;
	var _this = this;
	this.disX = e.clientX - this.MoveTarget.offsetLeft;
	this.disY = e.clientY - this.MoveTarget.offsetTop;
	if(this.MoveTarget.setCaptrue){//IE,解决文字选中
		this.MoveTarget.onmousemove = function(e){
			_this.fnMove(e);
			_this.json.movefn();
		};
		this.MoveTarget.onmouseup = function(){
			var this_ = this;
			_this.fnUp(this_);
		};
		this.MoveTarget.setCaptrue();//添加事件捕获
	}else{
		document.onmousemove = function(e){
			_this.fnMove(e);
			_this.json.movefn && _this.json.movefn();
		};
		document.onmouseup = function(){
			var this_ = this;
			_this.fnUp(this_);
		};
	}
}
Drag.prototype.fnMove = function(e){//鼠标移动,则div移动
	var e = e || window.event;
	var L = this.json ? this.range(e.clientX - this.disX,this.json.L[0],this.json.L[1]) : (e.clientX - this.disX);
	var T = this.json ? this.range(e.clientY - this.disY,this.json.T[0],this.json.T[1]) : (e.clientY - this.disY);
	this.MoveTarget.style.left = L + 'px';
	this.MoveTarget.style.top = T + 'px';
}
Drag.prototype.fnUp = function(this_){//鼠标松开,则停止
		this_.onmousemove = null;
		this_.onmouseup = null;
		this_.setCaptrue && this_.releaseCapture();//释放捕获
}
Drag.prototype.range = function(iNow,iMin,iMax){
	if(iNow>iMax){
		return iMax;
	}else if(iNow<iMin){
		return iMin;
	}else{
		return iNow;
	}
}
//拖拽改变大小
//使用方法 new scale($('press'),$('move'),{width:[100,200],height:[200,500]});(鼠标按住的目标,要移动的目标)
/*
var json = {
			width:[100,300],
			height:[200,500]
			}
*/
function Scale(pressTarget,MoveTarget,json){
	if(json){
		this.json = json;	
	}
	this.MoveTarget = MoveTarget;
	var _this = this;
	pressTarget.onmousedown = function(e){
		_this.onmousedownFn(e)
		};
}
Scale.prototype.onmousedownFn = function(e){
	var e = e || window.event;
	this.disX = e.clientX;
	this.disY = e.clientY;
	this.disW = this.MoveTarget.offsetWidth;
	this.disH = this.MoveTarget.offsetHeight;
	var _this = this;
	document.onmousemove = function(e){
		_this.mouseoverFn(e)
		};
	document.onmouseup = function(e){
		_this.mouseupFn(e)
		};
}
Scale.prototype.mouseoverFn = function(e){
	var e = e || window.event;
	this.W = this.json ? this.range(e.clientX - this.disX + this.disW,this.json.width[0],this.json.width[1]) : (e.clientX - this.disX + this.disW);
	this.H = this.json ? this.range(e.clientY - this.disY + this.disH,this.json.height[0],this.json.height[1]) : (e.clientY - this.disY + this.disH);
	this.MoveTarget.style.width = this.W + 'px';
	this.MoveTarget.style.height = this.H + 'px';
}
Scale.prototype.mouseupFn = function(){
	document.onmousemove = null;
	document.onmouseup = null;
}
Scale.prototype.range = function(iNow,iMin,iMax){
	if(iNow>iMax){
		return iMax;
	}else if(iNow<iMin){
		return iMin;
	}else{
		return iNow;
	}
}
//===============库扩展==============

$().extend = function(drag,fn){
	
}
/*
json = {
	dir:dir			//方向
	drag:DOM,		//拖拽的DOM
	scroll,DOM		//滚动的DOM
}
*/
TQuery.prototype.scrollBar = function(json){
	$('.scrollBar-btn').drag({
		'L':[0,0],
		'T':[0,$('.scrollBar').height()-$('.scrollBar-btn').height()],
		'movefn':function(){
			clearInterval($('.scrollBar-btn').get(0).timer);//清除滚轮定的时器
			var percent = $('.scrollBar-btn').top()/($('.scrollBar').height()-$('.scrollBar-btn').height());
			var top = $('.content p').height()-$('.content').height();
			$('.scrollBar-btn').text( parseInt(percent*100)+'%' );
			$('.content p').get(0).style.top = -( parseInt( top*percent ) ) + 'px';
		}
	})
}
})(window,document)//传入window,避免过度寻找作用域链