TQuery

我的仿jq库

当前为 2015-07-23 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/11045/63721/TQuery.js

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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,避免过度寻找作用域链