DOM库

作者: icessun | 来源:发表于2017-05-23 22:48 被阅读43次

    使用闭包的方式来封装:功能,兼容性的处理

    1. 类数组转数组:markArray-----类数组有两种:arguments(兼容所有的浏览器)和htmlCollection(只兼容标准浏览器)有时候也称为nodeList 元素集合
    2. json格式的字符串转为json格式的对象(一定是大括号里面有有双引号):jsonParseJSON还有一个方法:就是把json格式的对象转为字符串:JSON.stringify(对象)JSONJavaScript 原生格式,这意味着在 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);
    3. 生成随机数的函数rnd,给定一个范围,产生随机数,当传入错误的时候,返回一个0到1之间的随机数
    4. 求有定位元素到body的距离的函数offset,一层一层往上找,返回一个对象{left:xxx,top:xxx},距离body的左边和上边的距离,这个也要注意,IE8浏览器计算的时候不需要加上边框clientLeft和clientTop
    5. JS盒子模型一系列的offset,client,scorll,这样的属性值和设置的兼容处理:win,两个功能:获取属性值或者为属性设置值;求可视区的高度或者是被浏览器卷去的高度和宽度
    6. 获取非行间样式,也可以拿到行间样式:getCss,获取元素身上的某个样式值,这个也要处理兼容,对于浏览器,获取样式的方式是不一样的,getComputStyle和currentStyle,前面是标准浏览器后面是非标准浏览器。
    7. 限定容器的通过className来获取元素:getByClass,最后通过一个数组返回,获取容器下面所有类名的标签元素。
    8. 判断元素上面是否有这个类名:hasClass,返回一个布尔值,传入元素和类名
    9. 给元素身上添加类名:addClass,类名可以有多个
    10. 移除元素身上的某些类名:removeClass,传入元素,要删除的元素身上的类名,要注意多个类名之间的空格
    11. 获取元素上面的样式值:getCss,传入元素,元素身上的属性 返回对应的属性值
    12. 给元素设置样式值:setCss,传入的参数,元素,属性,属性值
    13. 给当前元素设置一组样式值:setGroupCss,传入的参数,元素,样式组对象
    14. 一个综合的方法:css,即可以设置样式值也可以获取样式值,参数是未知的,所以要通过arguments来判断,包含前面的三个方法,三个方法都有ele元素,核心是在于后面的参数个数不同,如果是对象,则是设置一组;如果是字符串,可能是获取也可能是设置一个
    15. 获取当前容器下,所有的孩子节点,getChildren,以一个数组返回,参数当前容器,容器下的元素名
    16. 求上一个哥哥元素prev,参数,当前的元素,返回这个元素的哥哥元素
    17. 求下一个弟弟元素next
    18. 求这个元素的所有哥哥元素prevAll
    19. 求这个元素的所有哥哥元素nextAll
    20. 求当前元素的相邻元素sibling
    21. 求当前元素的所有兄弟元素siblings
    22. 当前元素的所有索引next
    23. 求当前容器下的第一个子元素firstChild,参数当前容器,返回第一个子元素
    24. 求当前元素的最后一个元素lastChild
    25. 把元素插入到父容器的末尾appendChild
    26. 把元素插入到父容器的前面prependChild
    27. 把元素插到到指定元素的前面insertBefore
    28. 把元素插到指定元素的后面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,
                }
            }
            )();
    
    

    相关文章

      网友评论

        本文标题:DOM库

        本文链接:https://www.haomeiwen.com/subject/tnzgxxtx.html