一个轻量级的JavaScript库——pj.js
虽然像jQuery那样的库功能很强大,“品种”齐全,但是即使是jQuery1.4.2压缩版的也有70多kb,甚至比一个网页文件还大。而且有时候我们只需用其中一小部分的功能,不需要将整个jQuery库引进来。但我们又需要一个方便的库来协助开发网页。鉴于此,我就写了一个轻量级的库,命名为pj。很多选择器模式,方法名等引用了jQuery的模式或命名。部分代码如下:(可到这里下载:http://uers4.)/*pj.js
version: 2.0.3
email:pengju114@
@copyright: 2010 pengju ;
all rights reserved*/
(function(wnd,undef){
var doc=wnd.document;
var pj=function(selector,context){
return new pj.prototype.init(selector,context);
};
pj.prototype={
/***真正的构造函数***/
init:function(sel,cot){
/****上下文默认为document****/
cot=cot&&pj.isOBJ(cot)?cot:doc;
/****保存元素****/
var elems=[];
/****当前pj对象的计时器队列****/
this.timer={};
if(pj.isOBJ(sel))elems.push(sel);
else if(pj.isSTR(sel)){
sel=pj.trim(sel);
//#id
if(/^#\w+$/.test(sel))js.id(sel,cot,elems);
//tag
else if(/^\w+$/.test(sel))js.tag(sel,cot,elems);
// .className
else if(/^\.\w+$/.test(sel))(sel,cot,elems);
/****#id>tag****************
****取id下的所有tag元素****/
else if(/^#\w+>\w+$/.test(sel)){
var set=sel.split(">");
var t=cot.getElementById(set[0].replace(/^#/,""));
if(t){elems=js.tag(set[1],t,elems);}
}
/****tagtag****************
****取tag下的所有tag元素****/
else if(/^\w+>\w+$/.test(sel)){
var tag=sel.split(">");
var set=cot.getElementsByTagName(tag[0]);
if(set.length>0){
for(var k=0;k<set.length;k++)
js.tag(tag[1],set[k],elems);
}
}
//#id,tag, .className......
else if(/^([#|\.]?\w+,)+[#|\.]?\w+$/.test(sel)){
js.query(sel,cot,elems);
}
//#id[[,tag], .class][attr=value...]:[0[,1...]]
else if(/^([#|\.]?\w+,)*[#|\.]?\w+(\[(\w+=\w+,)*\w+=\w+\])?(:(\d+,)*\d+)?$/.test(sel)){
var a;
//#id[[,tag], .class]:[0[,1...]]
if(!/\[(\w+=\w+,)*\w+=\w+\]/.test(sel)){
a=sel.split(":");
var s=[];
js.query(a[0],cot,s);
js.findex(a[1],s,elems);
}
//#id[[,tag], .class][attr=value]:[0[,1...]]
else if(/:(\d+,)*\d+$/.test(sel)){
a=sel.split(":");
var all=[];
js.fattr(a[0],cot,all);
js.findex(a[1],all,elems);
}
//#id[[,tag], .class][attr=value]
else {
js.fattr(sel,cot,elems);
}
}
//<tag/>或者<tag>创建元素
else if(/^<\w+(\/)?>$/.test(sel)){
sel=sel.replace(/\//,"");
var sub=sel.lastIndexOf(">");
sub=sel.substring(1,sub);
sel=doc.createElement(sub);
if(sel){
elems.push(sel);
}
}
//HTML标记,如:<div>text</div>
else if(/^<(\S*?)[^>]*>.*?<\/\1>|<.*?\/>$/){
var text,tagName;
tagName=sel.indexOf(">");
text=sel.lastIndexOf("<");
text=sel.substring(tagName+1,text);
tagName=sel.substring(1,tagName);
tagName=doc.createElement(tagName);
if(tagName){
tagName.innerHTML=text;
elems.push(tagName);
}
}
}
return pj.merge(this,elems);
},//end init
/****取指定操作对象,
****如果不指明下标
****或越界则返回对
****象数组********
****如果当前操作对
****象只有一个则返
****回一个对象****/
get: function(index){
if(this.length==1)return this[0];
else if(index!==undef)return this[index];
else return Array.prototype.slice.call(this,0);
},
/****以当前所有操作
****对象为上下文执
****行fn函数并返回
****当前pj对象****/
each:function(fn,arg){//arg可选
if(pj.isFn(fn))
for(var i=0;i<this.length;i++){
fn.call(this[i],arg);
}
return this;
},
/****给当前对象集合添加事件监听器***
****参数是一个对象*****************
****如{click:function([e]){……}}**/
addListener:function(set){
if(!pj.isOBJ(set))return this;
for(var e in set){
if(wnd.addEventListener)
this.each(function(){this.addEventListener(e,set[e],false);});
else if (wnd.attachEvent)
this.each(function(){this.attachEvent("on"+e,pj.extend(this,set[e]));});
}
return this;
},
attr:function(name/*[,value]*/){//只有一个参数则取属性值,有两个参数则设置属性值
var set=[],arg=arguments;
if(arg.length==1){//get attribute
this.each(function(){set.push(this.getAttribute(name+""));});
return this.length==1?set[0]:set;
}
else if(arg.length==2){
this.each(function(){this.setAttribute(name+"",arg[1]+"");});
}
return this;
},
removeAttr:function(name){
if(name)this.each(function(){
try{
this.removeAttribute(name);
}catch(e){
try{
delete this[name];
}catch(et){}
}
});
return this;
},
stop:function(name){//name: 方法名
if(name&&this.timer[name]){
wnd.clearInterval(this.timer[name]);
delete this.timer[name];
}
return this;
},
//将元素追加到指定的DOM元素 ,如果指定的参数不是对象则加到document.body
appendTo:function(target){
var t=doc.body;
if(target&&pj.isOBJ(target)&&target.nodeType&&target.nodeType==1){
t=target;
}
this.each(function(){t.appendChild(this);});
return this;
},
addClassName:function(name){
if(name){
name=" "+name;
this.each(function(){
this.className+=name;
});
}
return this;
},
removeClassName:function(name){
if(name){
this.each(function(){
this.className=this.className.replace(name,"");
});
}
return this;
},
setClassName:function(name){
if(name){
this.each(function(){
this.className=name;
});
}
return this;
}
};//end prototype
//辅佐对象,仅在内部使用
var js={
/****s是形如#id[,#id]……的字符串******
****并以c为上下文取对象,并放到a数组中*/
id:function(s,c,a){
s=s.split(",");
var o;
for(var i=0;i<s.length;i++){
o=c.getElementById(s[i].replace(/^#/,""));
if(o)a.push(o);
}
/****返回对象数组****/
return a;
},
/****s是形如 .className的字符串****/
cname:function(s,c,a){
s=s.replace(/^\./,"");
var x=c.getElementsByTagName("*");
for(var i=0;i<x.length;i++){
if(x[i].className==s)a.push(x[i]);
}
/****返回对象数组****/
return a;
},
/****t是标签****/
tag:function(t,c,a){
t=c.getElementsByTagName(t);
/****返回对象数组****/
return pj.merge(a,t);
},
/****str是形如 #id[.className|tag]... 的字符串****/
query:function(str,c,a){
str=str.split(",");
for(var i=0;i<str.length;i++){
if(/^#\w+$/.test(str[i])){a=this.id(str[i],c,a);}
else if(/^\w+$/.test(str[i])){a=this.tag(str[i],c,a);}
else if(/^\.\w+$/.test(str[i])){a=(str[i],c,a);}
}
return a;
},
/****通过属性过滤元素****/
fattr:function(str,c,to){
str=str.split("[");
var attr=str[1].replace(/\]$/,"").split(",");
var set=[],j,b;
/****str[0]是形如#id|tag|.className...[attr=vlaue]的字符串****/
set=this.query(str[0],c,set);
for(var i=0;i<set.length;i++){
for(j=0;j<attr.length;j++){
b=attr[j].split("=");
try{
if(set[i].getAttribute(b[0])==b[1])to.push(set[i]);
}catch(e){break;}
}
}
},
/****通过下标过滤元素,*********************
****str是形如 0,2,5……的字符串***********
****并从src中选择符合条件的元素复制到to中*/
findex:function(str,src,to){
str=str.split(",");
for(var l=0;l<str.length;l++){
str[l]=parseInt(str[l]);
if(str[l]<src.length)to.push(src[str[l]]);
}
}
};
/****将pj的prototype********
****赋给pj.prototype.init的
**** prototype ************/
pj.prototype.init.prototype=pj.prototype;
pj.ready=function(fn){//当页面加载完成时调用fn
if(doc.getElementById&&doc.getElementsByTagName)fn();
else setTimeout(function(){pj.ready(fn);},100);
};
/****target将继承方法fn*****
****并且fn的上下文是target*/
pj.extend=function(target,fn){
return function(){return fn.apply(target,arguments);};
};
/****将一个对象中的属性
****或方法绑定到指定对
****象,如果只有一个参
****数则绑定到pj对象**/
pj.bind=pj.prototype.bind=function(){
var tar,src;
if(arguments.length>1){
src=arguments[1];
tar=arguments[0];
}
else if(arguments.length==1){
tar=this;
src=arguments[0];
}
else {
tar={};
src={};
}
for(var e in src){tar[e]=src[e];}
return tar;
};
pj.bind(pj,{//绑定一般方法
/****判断是否是正常的对象或DOM对象****/
isOBJ:function(t){
return typeof t==="object"
&&(Object.prototype.toString.call(t)==="[object Object]"
||typeof t.nodeType==="number");
},
/****判断fn是否是一个函数****/
isFn:function(fn){return Object.prototype.toString.call(fn)==="[object Function]"},
/****判断t是否是一个数组****/
isArray:function(t){return Object.prototype.toString.call(t)==="[object Array]";},
/****判断字符串****/
isSTR:function(t){return Object.prototype.toString.call(t)==="[object String]"},
/****去除str中所有的空格****/
trim:function(str){return str.replace(/\s+/g,"");},
/****将src中的数据整合到tar中****/
merge: function( tar,src ) {
var i=tar.length||0,j=0;
if(typeof src.length==="number"){
for(var l=src.length;j<l;j++ )tar[i++]=src[j];
}
else{
while(src[j]!==undef){tar[i++]=src[j++];}
}
tar.length = i;
return tar;
}
});
pj.prototype.bind({
getStyle:function(name){//取元素样式值
var st=[];
this.each(function(){
//处理IE取opacity
if(/opacity/i.test(name)&&this.currentStyle&&!wnd.getComputedStyle){
var a= this.currentStyle.filter+"",v;
v=a.toLowerCase().indexOf("opacity=");
v=v>=0?(parseFloat(a.substring(v+8))) + "" :"100";
st.push(v);
}
else if(this.style[name])//如果属性存在,那么它已被设置
st.push(this.style[name]);
else if(this.currentStyle)//尝试用IE方法
st.push(this.currentStyle[name]);
else if(wnd.getComputedStyle)
st.push(wnd.getComputedStyle(this,null)[name]);//W3C
else st.push(null);
});
//如果对象集合长度为1则返回属性值,否则返回属性值数组
return st.length==1?st[0]:st;
},
/****设置元素属性,source为对象{color:"red",display:"block"[...]}
****或者source为属性名,value为值****/
setStyle:function(source/*,value*/){
if(arguments.length>1&&!pj.isOBJ(source)){
var name=arguments[0];
source={};
source[name]=arguments[1];
}
if(pj.isOBJ(source))
for(var v in source){
if(/opacity/i.test(v))
this.each(function(){pj.setOpacity(this,parseInt(source[v]));});
else this.each(function(){this.style[v]=source[v];});
}
return this;
}
});
/****添加事件监听器的快捷方式****/
pj.prototype.bind({
abort:function(fn){
return this.addListener({"abort":fn});
},
blur:function(fn){
return this.addListener({"blur":fn});
},
change:function(fn){
return this.addListener({"change":fn});
},
click:function(fn){
return this.addListener({"click":fn});
},
dblclick:function(fn){
return this.addListener({"dblclick":fn});
},
error:function(fn){
return this.addListener({"error":fn});
},
focus:function(fn){
return this.addListener({"focus":fn});
},
keydown:function(fn){
return this.addListener({"keydown":fn});
},
keypress:function(fn){
return this.addListener({"keypress":fn});
},
keyup:function(fn){
return this.addListener({"keyup":fn});
},
load:function(fn){
return this.addListener({"load":fn});
},
unload:function(fn){
return this.addListener({"unload":fn});
},
mousedown:function(fn){
return this.addListener({"mousedown":fn});
},
mousemove:function(fn){
return this.addListener({"mousemove":fn});
},
mouseout:function(fn){
return this.addListener({"mouseout":fn});
},
mouseover:function(fn){
return this.addListener({"mouseover":fn});
},
mouseup:function(fn){
return this.addListener({"mouseup":fn});
},
reset:function(fn){
return this.addListener({"reset":fn});
},
resize:function(fn){
return this.addListener({"resize":fn});
},
select:function(fn){
return this.addListener({"select":fn});
},
submit:function(fn){
return this.addListener({"submit":fn});
}
});
//这样定义方便选择
pj.stopBubble=function(e){//事件发生时停止冒泡
if(e&&e.stopPropagation)e.stopPropagation();//W3C
else wnd.event.cancelBubble=true;//IE
};
pj.stopDefault=function(e){//停止浏览器的默认动作
if(e&&e.preventDefault)e.preventDefault();//W3C
else wnd.event.returnValue=false;//IE
return false;
};
pj.pageHeight=function(){//取得当前页面潜在的高度
return doc.documentElement&&doc.documentElement.scrollHeight
||doc.body.scrollHeight;
};
pj.pageWidth=function(){//取得当前页面潜在的宽度
return doc.documentElement&&doc.documentElement.scrollWidth
||doc.body.scrollWidth;
};
pj.windowHeight=function(){//取得浏览器视窗的高度
var de=doc.documentElement;//IE中的一个快捷方式
return self.innerHeight||(de&&de.clientHeight)||doc.body.clientHeight;
};
pj.windowWidth=function(){//取得浏览器视窗的宽度
var de=doc.documentElement;//IE中的一个快捷方式
return self.innerWidth||(de&&de.clientWidth)||doc.body.clientWidth;
};
pj.setOpacity=function(t,v){//设置透明度
//IE,在IE里如果不行,就把position设为absolute或者将display设为block
if(t.filters)t.style.filter="alpha(opacity="+v+")";
else t.style.opacity=v/100;
};
pj.bind(pj,{//绑定通用的方法
resetCSS:function(obj,p){
var old={};
for(var i in p){
old[i]=obj.style[i];//保存旧值
obj.style[i]=p[i];//设置新值
}
return old;//用来复原
},
x:function(obj){//取元素相对于整个页面的x坐标
return obj.offsetParent?
obj.offsetLeft+pj.x(obj.offsetParent):obj.offsetLeft;
},
y:function(obj){//取元素相对于整个页面的y坐标
return obj.offsetParent?
obj.offsetTop+pj.y(obj.offsetParent):obj.offsetTop;
},
wh:function(obj,name)
{
var v,self=pj(obj);
if(self.getStyle("display")!="none")
{
if(name=="height")v=obj.offsetHeight
||parseInt(self.getStyle("height"));
else if(name=="width")v=obj.offsetWidth
||parseInt(self.getStyle("width"));
return v;
}
var old=pj.resetCSS(
obj,{display:'block',
visibility:'hidden',
position:'absolute'});
if(name=="height")v=obj.clientHeight||self.height();
else if(name=="width")v=obj.clientWidth||self.width();
self.setStyle(old);
return v;
}//end wh
});
pj.prototype.bind({//绑定取元素尺寸方法
left:function(){//取得元素想对于整个文档的X位置
var set=[];
this.each(function(){set.push(pj.x(this));});
return this.length==1?set[0]:set;
},
top:function(){//取得元素想对于整个文档的Y位置
var set=[];
this.each(function(){set.push(pj.y(this));});
return this.length==1?set[0]:set;
},
right:function(){
var set=[];
this.each(function(){
set.push(pj.x(this)+pj.wh(this,"width"));
});
return this.length==1?set[0]:set;
},
bottom:function(){
var set=[];
this.each(function(){
set.push(pj.y(this)+pj.wh(this,"height"));
});
return this.length==1?set[0]:set;
},
height:function(){//元素高度
var set=[];
this.each(function(){set.push(pj.wh(this,"height"));});
return this.length==1?set[0]:set;
},
width:function(){//元素宽度
var set=[];
this.each(function(){set.push(pj.wh(this,"width"));});
return this.length==1?set[0]:set;
}
});
……(内容过长)
/****将pj映射到全局对象上****/
wnd.pj=pj;
})(window);