使用闭包的方式来封装:功能,兼容性的处理
- 类数组转数组:
markArray
-----类数组有两种:arguments(兼容所有的浏览器)和htmlCollection(只兼容标准浏览器)有时候也称为nodeList 元素集合
json
格式的字符串转为json
格式的对象(一定是大括号里面有有双引号):jsonParse
,JSON
还有一个方法:就是把json格式
的对象转为字符串:JSON.stringify(对象)
,JSON
是JavaScript
原生格式,这意味着在JavaScript
中处理JSON
数据不需要任何特殊的API
或工具包。eval(({'aa':11,'ccc':'csc','age':11}))
得到的结果是:Object {aa: 11, ccc: "csc", age: 11}
或者是var jsonStr = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}'; JSON.parse(jsontext);
- 生成随机数的函数
rnd
,给定一个范围,产生随机数,当传入错误的时候,返回一个0到1之间的随机数- 求有定位元素到
body
的距离的函数offset
,一层一层往上找,返回一个对象{left:xxx,top:xxx}
,距离body
的左边和上边的距离,这个也要注意,IE8
浏览器计算的时候不需要加上边框clientLeft和clientTop
- 对
JS盒子模型一系列的offset,client,scorll,这样的属性值和设置
的兼容处理:win
,两个功能:获取属性值或者为属性设置值;求可视区的高度或者是被浏览器卷去的高度和宽度- 获取非行间样式,也可以拿到行间样式:
getCss
,获取元素身上的某个样式值,这个也要处理兼容,对于浏览器,获取样式的方式是不一样的,getComputStyle和currentStyle
,前面是标准浏览器后面是非标准浏览器。- 限定容器的通过
className
来获取元素:getByClass
,最后通过一个数组返回,获取容器下面所有类名的标签元素。- 判断元素上面是否有这个类名:
hasClass
,返回一个布尔值,传入元素和类名- 给元素身上添加类名:
addClass
,类名可以有多个- 移除元素身上的某些类名:
removeClass
,传入元素,要删除的元素身上的类名,要注意多个类名之间的空格- 获取元素上面的样式值:
getCss
,传入元素,元素身上的属性 返回对应的属性值- 给元素设置样式值:
setCss
,传入的参数,元素,属性,属性值- 给当前元素设置一组样式值:
setGroupCss
,传入的参数,元素,样式组对象- 一个综合的方法:
css
,即可以设置样式值也可以获取样式值,参数是未知的,所以要通过arguments
来判断,包含前面的三个方法,三个方法都有ele
元素,核心是在于后面的参数个数不同,如果是对象,则是设置一组;如果是字符串,可能是获取也可能是设置一个- 获取当前容器下,所有的孩子节点,
getChildren
,以一个数组返回,参数当前容器,容器下的元素名- 求上一个哥哥元素
prev
,参数,当前的元素,返回这个元素的哥哥元素- 求下一个弟弟元素
next
,- 求这个元素的所有哥哥元素
prevAll
- 求这个元素的所有哥哥元素
nextAll
- 求当前元素的相邻元素
sibling
- 求当前元素的所有兄弟元素
siblings
- 当前元素的所有索引
next
- 求当前容器下的第一个子元素
firstChild
,参数当前容器,返回第一个子元素- 求当前元素的最后一个元素
lastChild
- 把元素插入到父容器的末尾
appendChild
- 把元素插入到父容器的前面
prependChild
- 把元素插到到指定元素的前面
insertBefore
- 把元素插到指定元素的后面
insertAfter
var utils=(function(){
// 判断是否标准浏览器 要是在window上面有这个属性getComputedStyle 就说明是标准的浏览器,不是IE6-8 惰性思想
var frg='getComputedStyle' in window;
// 类数组转数组 参数 类数组 返回 数组
function makeArray(arg){
var ary=[]; // 返回一个数组
if(frg){
//说明是标准浏览器,可以直接调用Array的原型上面的slice方法去克隆arg上面的数据,返回一个数组
// arguments兼容所有的浏览器,但是htmlCollection只兼容标准浏览器 ,此时说明是标准浏览器,支持slice.call
ary=Array.prototype.slice.call(arg);
}else{
// 非标准的浏览器
for(var i=0;i<arg.length;i++){
ary.push(arg[i]);
}
}
return ary;
}
// 把json格式的字符串转为json格式的对象 参数:json格式的字符串 返回 json格式的对象
function jsonParse(strJson){
// 如果浏览器支持JSON 直接使用JSON.parse 否者使用evel来计算
return 'JSON' in window?JSON.parse(strJson):eval('('+strJson+')');
}
// 随机数 参数 随机数产生的范围 返回: 随机数
function rnd(n,m){
n=Number(n);
m=Number(m);
if(isNaN(n)||isNaN(m)){
return Math.random();// 传错参数
}
// n要小于m
if(n>m){
var tem=m;
m=n;
n=tem;
}
return Math.round(Math.random()*(m-n)+n);
}
// 获取元素到body的距离 参数:元素 返回:一个对象到body的left和top的距离
function offset(ele){
// 首先获取元素到定位父级的距离
var l=ele.offsetLeft;
var t=ele.offsetTop;
var par=ele.offsetParent;
// 如果有定位父级 就会一级一级往上面找
while(par){
if(window.navigator.userAgent.toUpperCase().indexOf('MSIE 8.0')== -1){
// 不是IE8 浏览器 需要加上边框的宽度
l+=par.clientLeft;
t+=par.clientWidth;
}
// IE8 浏览器不需要添加边框宽度
l+=par.offsetLeft;
r+=par.offsetTop;
par=par.offsetParent;
}
return {left:l,top:t};
}
// 获取或者设置元素的属性值 对js盒子模型的兼容处理;第二个参数来区别是获取还是设置
function win(attr,value){
if(typeof value === 'undefined'){
// if(value == null)
// 说明是获取 有返回值 兼容浏览器,前面是标准后面是非标准
return document.documentElement[attr]||document.body[attr];
}
// 设置属性
document.documentElement[attr]=document.body[attr];
}
// 获取指定容器中的className 参数:指定容器 className
function getByClass(strClass,parent){
parent=parent||document;
if(frg){
// 通过className获取元素可能有多个,返回的是一个类数组 .toString()可以查看----> [object HTMLCollection],转成数组好操作
return this.makeArray(parent.getElementsByClassName(strClass));
}
var ary=[];
// 通过空格来分割类名
var aryClass=strClass.split(/\s+/g);
// 获取父容器下面的所有对象标签元素 整个html页面的标签
var nodeList=parent.getElementsByTagName('*');
for(var i=0;i<nodeList.length;i++){
var cur=nodeList[i];
// 状态判断法
var bOk=true;
for(var j=0;j<aryClass.length;j++){
// 拼接变量 new RegExp
// var reg=new RegExp('\\b'+aryClass[j]+'\\b');
var reg=new RegExp('(^| +)'+aryClass[j]+'( +|$)');
if(!reg.test(cur.className)){
bOk=false;
break;
}
}
if(bOk){
ary.push(cur);
}
}
return ary;
}
// 判断元素上是否有这个类名 参数:元素 类名 返回 布尔值
function hasClass(ele,cName){
var reg=new RegExp('(^| +)'+cName+'( +|$)');
return reg.test(ele.className);
}
// 如果元素身上没有某些class名,可以添加1个或者多个 参数:元素 className
function addClass(ele,strClass){
var aryClass=strClass.split(/\s+/g);//使用字符串的split方法以空格来分隔字符串
for(var i=0;i<aryClass.length;i++){
if(!this.hasClass(ele,aryClass[i])){
// 开头结尾的空格去掉 中间的空格替换为1个空格
ele.className=ele.className.replace(/(^ +)|( +$)/g,'').replace(/\s+/g,' ')
ele.className+=' '+aryClass[i];
}
}
}
// 移除元素上的某些class名 参数:元素 className
function removeClass(ele,strClass){
// 字符串转数组
var aryClass=strClass.split(/\s+/g);
// 判断元素的class名是否包含数组中的该项 有 删除
for(var i=0;i<aryClass.length;i++){
var reg=new RegExp('(^| +)'+aryClass[i]+'( +|$)','g');
if(reg.test(ele.className)){
ele.className=ele.className.replace(reg,' ').replace(/(^ +)|( +$)/g,'').replace(/\s+/g,' ');
}
}
}
// 获取元素上面的样式值 参数:元素 属性 返回:对应的属性值
function getCss(ele,attr){
var value=null,reg=null;
if(frg){
value=getComputedStyle(ele,false)[attr];
}else{ // IE6-8
if(attr=='opacity'){
value=ele.currentStyle.filter;
reg=/^alpha\(opacity[=:](\d+)\)$/;
return reg.test(value)?RegExp.$1/100:1; // reg.exec(value)[1] 取得第一个小分组的数据
}else{
value=ele.currentStyle[attr];
}
}
// 去掉单位
reg=/^([+-]?(\d|([1-9]\d+))(\.\d+)?)(px|pt|rem|em)$/;
return reg.test(value)?parseFloat(value):value;
}
// 给元素设置样式 参数:元素 属性 属性值
function setCss(ele,attr,value){
// 处理浮动
if(attr==='float'){
ele.style.cssFloat=value;// firefox
ele.style.styleFloat=value;// ie
return ;
}
// 处理透明度
if(attr==='opacity'){
ele.style[attr]=value;// 标准浏览器
ele.style.filter='alpha(opacity='+value*100+')'
return;
}
// 处理单位
var reg=/(width|height|top|right|bottom|left|((margin|padding)(Top|Right|Bottom|Left)?))/g;
if(reg.test(attr)&& !isNaN(value)){ // 不会出现auto % 等情况
value=value+'px';
}
ele.style[attr]=value;// 最核心的代码
}
// setGroupCss 给当前元素设置一组样式 参数:元素 样式对象 键值对的形式呈现
function setGroupCss(ele,opt){
// 遍历对象的方法 for in 循环
for(var attr in opt){
this.setCss(ele,attr,opt[attr]);
}
}
// css 三合一的方法 获取,设置一个,设置一组 参数是未知的,所以要通过arguments来判断
// 三个方法都有ele元素,核心是在于后面的参数个数不同,如果是对象,则是设置一组;如果是字符串,可能是获取也可能是设置一个
function css(ele){
var argTwo=arguments[1];// 第二个参数
// 判断第二个参数的数据类型
if(typeof argTwo==='string'){
var argThree=arguments[2];// 第三个参数
// 如果没有第三个参数,是获取
if(typeof argThree==='undefined'){
return this.getCss(ele,argTwo);
}else{
// 有第三个参数 设置样式
this.setCss(ele,argTwo,argThree);
}
}
// 对象数据类型的检测,直接使用toString();是对象,说明是设置一组
if(argTwo.toString()==='[object Object]'){
this.setGroupCss(ele,argTwo);
}
}
// getChildren: 获取当前容器下的所有元素 参数:当前容器 指定的元素名 返回:符合条件的元素数组
function getChildren(parent,tagName){
var childNodes=parent.childNodes;// 获取当前容器下所有的孩子节点
var ary=[];
for(var i=0;i<childNodes.length;i++){
var cur=childNodes[i];
// 先判断是一个元素节点 nodeType==1
if(cur.nodeType==1){
// 如果第二个参数没有,就说明对当前容器下的元素节点不过滤,直接放数组里面
if(typeof tagName==='undefined'){
ary.push(cur);
}else{
// 说明要过滤
if(cur.tagName.toLowerCase()===tagName.toLowerCase()){
ary.push(cur);
}
}
}
}
return ary;
}
// 求上一个哥哥元素 参数:要求的当前元素ele 返回:这个元素的哥哥元素
function prev(ele){
if(frg){
return ele.previousElementSibling; // 标准浏览器 获取当前元素的上一个哥哥元素
}
var pre=ele.previousSibling; // 非标准的浏览器,这个方法获取的哥哥元素,可能包含换行,或者注释
// 主要pre存在且节点类型不等于1就一直查找其哥哥节点
while(pre&&pre.nodeType!==1){
pre=pre.previousSibling;
}
return pre;
}
// 下一个弟弟节点
function next(ele){
if(frg){
return ele.nextElementSibling;
}
var nex=ele.nextSibling; // 下一个弟弟节点
while(nex && nex.nodeType!==1){
nex=nex.nextSibling;
}
return nex;
}
// 当前元素的所有的哥哥元素
function prevAll(ele){
var ary=[];
var pre=this.prev(ele);// 先求出上一个哥哥元素
// 不知道pre是否还有哥哥元素,所以要循环查找
while(pre){
ary.push(pre);
pre=this.prev(pre);
}
return ary;
}
// 当前元素的所有弟弟元素
function nextAll(ele){
var ary=[];
var nex=this.next(ele);
while(nex){
ary.push(nex);
nex=this.next(nex);
}
return ary;
}
// 当前元素的相邻元素 就是上一个哥哥元素和下一个弟弟元素
function sibling(ele){
var prev=this.prev(ele);
var next=this.next(ele);
var ary=[];
if(prev)ary.push(prev);
if(next)ary.push(next);
return ary;
}
// 当前元素的所有兄弟元素
function siblings(ele){
// 返回的是一个数组,利用数组的方法:concat()
return this.prevAll(ele).concat(this.nextAll(ele));
}
// 当前元素的所有索引
function index(ele){
return this.prevAll(ele).length;
}
//求当前容器下的第一个子元素
function firstChild(parent){
var aChild=this.getChildren(parent);
return aChild[0];
}
// 当前容器下的最后一个元素
function lastChild(parent){
var aChild=this.getChildren(parent);
return aChild[aChild.length-1];
}
// 把元素插到父容器的末尾
function appendChild(parent,ele){
parent.appendChild(ele);
}
// 把元素插到父容器的前面
function prependChild(parent,ele){
var first=this.firstChild(parent);
if(first){
parent.insertBefore(ele,first);
}else{
parent.appendChild(ele);
}
}
// 把元素插到到指定元素的前面
function insertBefore(newEle,oldELe){
oldELe.parentNode.insertBefore(newEle,oldELe);
}
// 把元素插到指定元素的后面
function insertAfter(newEle,oldEle){
var nex=this.next(oldEle);// 先求出oldELe的弟弟
if(nex){
oldEle.parentNode.insertBefore(newEle,nex);
}else{
oldEle.parentNode.appendChild(newEle);
}
}
return {
makeArray:makeArray,
jsonParse:jsonParse,
rnd:rnd,
offset:offset,
win:win,
getByClass:getByClass,
hasClass:hasClass,
addClass:addClass,
removeClass:removeClass,
getCss:getCss,
setCss:setCss,
setGroupCss:setGroupCss,
css:css,
getChildren:getChildren,
prev:prev,
next:next,
prevAll:prevAll,
nextAll:nextAll,
sibling:sibling,
siblings:siblings,
index:index,
firstChild:firstChild,
lastChild:lastChild,
appendChild:appendChild,
prependChild:prependChild,
insertBefore:insertBefore,
insertAfter:insertAfter,
}
}
)();
网友评论