首页 > 代码库 > 获取dom对象(4)

获取dom对象(4)

<html><head>    <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />    <title>获取dom对象</title></head><body>    <input id="btn1" class="btn1" type="button" value="http://www.mamicode.com/mybtn1" />    <input name="btn1" class="btn1" type="button" value="http://www.mamicode.com/mybtn2" />    <img src="" alt="img1" />    <img src="" alt="img2" />    <div id="mydiv">        <input class="btn2" type="button" data="http://www.mamicode.com/test" value="http://www.mamicode.com/mybtn3" />        <input class="btn2" type="button" value="http://www.mamicode.com/mybtn4" />    </div></body></html><script type="text/javascript">    //兼容ie浏览器测试    var console = console || {};    console.log = console.log || function(a){        alert(a);    }    /*    在实际开发中,可能更多的时候我们会使用jquery框架.    而且使用框架获取dom对象,相当的简单和方便.    这是由于这些框架封装了获取dom的方法,并且封装的看不太懂.    那我们就来尝试着自己封一下.    */    /*    先来一个最简单的,简单封装一下getElementById    */    //封装getElementById    function $(id){        var dom = null;        if(id != null && id != ""){            dom = document.getElementById(id);        }        return dom;    }    /*    //通过$方法获取dom    var btn1 = $("btn1");    //输出btn1的value    console.log(btn1.value);//mybtn1    */    /*    这种方式就看起来比较眼熟了.    但是怎么获取class相同的dom呢.    我们好像很习惯直接使用class去获取dom,我想这可能是分工的原因.    经常我们开发的时候,已经有美工MM,帮我们做好了静态页面,然后页面中有很多已经很好的class供我们选择.    其实我是比较反对任何时候都直接使用class去获取dom,不管你用什么框架.    因为我们知道通过id获取dom是效率最高.    既然如此,为什么还要提供这样的方法,我只能说懒是人的共性.    */    /*    那怎么做呢?    第一步,通过getElementsByTagName(),获取到整个文档的所有元素.    第二步,判断这些元素的className是否是我们需要的.    */    function $(classname){        var dom = [];        if(classname != null && classname != ""){            //获取全部元素            var all = document.getElementsByTagName("*");            for(var i = 0,len = all.length; i < len; i++) {                var obj = all[i];                if(obj.className === classname){                    //保存匹配的dom                    dom.push(obj);                }            }        }        return dom;    }    /*    //获取class=btn1的元素    var btns = $("btn1");    for(var i = 0,len = btns.length; i < len; i++){        console.log(btns[i].value);//mybtn1,mybtn2    }    */    /*    我们得到class相同的元素,但是这样的调用方式并不是我们所习惯的.    那我们仿造jquery的样子,稍微修改一下.    jquery中id使用#开头,class使用.开头    */    /*    思路:    第一步,获取字符串的第一个字符.    第二步,判断第一个字符的类别,做不同的处理.    */    function $(str){        var dom = null;        if(str != null && str != ""){            //获取标识,得到字符串的第一个字符            var c = str.charAt(0);            switch(c){                case "#":                    //截取ID,从第一个字符开发到最后                    var id = str.substring(1);                    dom = document.getElementById(id);                break;                case ".":                    dom = [];                    //截取                    var classname = str.substring(1);                    if(classname != null && classname != ""){                        //获取全部元素                        var all = document.getElementsByTagName("*");                        for(var i = 0,len = all.length; i < len; i++) {                            var obj = all[i];                            if(obj.className === classname){                                //保存匹配的dom                                dom.push(obj);                            }                        }                    }                break;                default:                    //如果第一个字符不是我们想要的,做一个容错处理                    dom = document.getElementById(str);                break;            }        }        return dom;    }    var btn1 = $("#btn1");    console.log(btn1.value);//mybtn1    var btns = $(".btn1");    for(var i = 0,len = btns.length; i < len; i++){        console.log(btns[i].value);//mybtn1,mybtn2    }    /*    这样看起来就有那么点像jquery的感觉了,这仅仅是看起来像而已.    因为jquery的选择器比这要复杂的多的多的多.    这都不要紧,我们不是想造一个jquery,我们只是在按自己的思路封装代码,好让我们的工作变得简单.    */    /*    实际开发过程中,需求总是多变而且复杂的,所以这样简单的封装并不能让我们的工作变的简单.    那怎么办呢?    简单分析一下,获取dom元素,有用的标识无非三种(id,tag,attr),其实name也是一种属性值.    那么,根据优先级我们组合一下各种情况.    id    id + tag    id + tag + attr    tag    tag + attr    attr(只有当是name的时候有效,不然就应该是 * + attr)    */    /*    思路:    第一步,申明一个函数接收三个参数id,tag,attr.    第二步,根据不同的组合编写逻辑.    */    /*    id:string    tag:string    attr:属性值都是key=value,所以第三个参数应该对象    */    function getDom(id,tag,attr){        var dom = null;        //获取传入参数的个数        var len = arguments.length;        switch(len){            case 1:                //如果只传了一个参数,那么符合只根据 id 查找                //我们直接通过getElementById()获取dom                dom = document.getElementById(arguments[0]);            break;            case 2:                //如果传了两个参数,那么符合 id + tag                //我们知道js是支持获取全部文档指定tag的元素,                //所以当id传入空串的时候,就能满足这种情况.(但是这种效率是低下的,可以根据实际情况是否需要必须指定id)                //ok,先判断id是否有值                var id = arguments[0] || "";                var tag = arguments[1] || "";                if(id !== "" && tag !== ""){                    dom = document.getElementById(id).getElementsByTagName(tag);                }                else{                    if(tag !== ""){                        dom = document.getElementsByTagName(tag);                    }                    else{                        //都传入空值不合法                    }                }            case 3:                //如果三个参数都有,就比较复杂了,我们列举一下.                // id + tag + attr                // "" + tag + attr                // "" + "" + attr(只能是name)                // id + "" + attr(这种是不成立的,因为id唯一)                //但是数学的排列组合不是这样的,还有 "" + tag + ""                //我们细想一下,这样就应该只传入两个参数呀                var id = arguments[0] || "";                var tag = arguments[1] || "";                //属性值都是key=value,所以第三个参数应该对象                var attr = arguments[2] || {};                if(id !== ""){                    if(tag !== "" && attr !== ""){                        // id + tag + attr                        dom = [];                        //属性                        var key = null;                        //属性值                        var aval = null;                        //解析attr                        for(var k in attr){                            key = k;                            aval = attr[k];                        }                        //获取某个id下的全部tag元素                        var all = document.getElementById(id).getElementsByTagName(tag);                        for(var i = 0,len = all.length; i < len; i++) {                            var obj = all[i];                            if(obj.getAttribute(key) === aval){                                //保存匹配的dom                                dom.push(obj);                            }                        }                    }                    else{                        //不应该成立情况                        // id + tag + "" (应该只传入两个参数)                        // id + "" + attr(这种是不成立的,因为id唯一)                    }                }                else{                    if(tag !== ""){                        // "" + tag + attr                        dom = [];                        //属性                        var key = null;                        //属性值                        var aval = null;                        //解析attr                        for(var k in attr){                            key = k;                            aval = attr[k];                        }                        //获取全部tag元素                        var all = document.getElementsByTagName(tag);                        for(var i = 0,len = all.length; i < len; i++) {                            var obj = all[i];                            if(obj.getAttribute(key) === aval){                                //保存匹配的dom                                dom.push(obj);                            }                        }                    }                    else{                        // "" + "" + attr(只能是name)                        //js只提供了getElementByName的接口,所以不能直接获取其它属性值的dom                        //如果要获取其它属性值的dom,只能采用 tag + attr                        dom = [];                        //属性                        var key = null;                        //属性值                        var aval = null;                        //解析attr                        for(var k in attr){                            key = k;                            aval = attr[k];                        }                        if(key === "name"){                            dom = document.getElementsByName(aval);                        }                        else{                            //参数不合法                        }                    }                }            break;        }        return dom;    }    /*    到这里,我们基本就完成了关于获取dom的封装,我们测试一下各种情况    */    //id    var dom = getDom("btn1");    console.log(dom.value);//mybtn1    //id + tag    var dom = getDom("mydiv","input");    for(var i in dom){        console.log(dom[i].value);//mybtn3,mybtn4    }    // "" + tag    var dom = getDom("","input");    for(var i in dom){        console.log(dom[i].value);//mybtn1,mybtn2,mybtn3,mybtn4    }    //id + tag + attr    var dom = getDom("mydiv","input",{"data":"test"});    for(var i in dom){        console.log(dom[i].value);//mybtn3    }    // "" + tag + attr    var dom = getDom("","input",{"class":"btn1"});    for(var i in dom){        console.log(dom[i].value);//mybtn1,mybtn2    }    // "" + "" + attr(只能是name)    var dom = getDom("","",{"name":"btn1"});    for(var i = 0,len = dom.length; i < len; i++){        console.log(dom[i].value);//mybtn2    }    /*    好了,有点小意思了对吧,这样就应该可以满足需要了.    但是,回头我看一下封装好的getDom,在处理第三种情况的时候有一些代码冗余了.    我们可以不可优化一些呢.    思考一下:    可以把冗余的代码写成一个函数.    */    /*    id:string    tag:string    attr:属性值都是key=value,所以第三个参数应该对象    */    function getDom(id,tag,attr){        //封装第三种情况,根据tag,attr获取dom        function getbytag(id,tag,attr){            var dom = [];            //属性            var key = null;            //属性值            var aval = null;            //解析attr            for(var k in attr){                key = k;                aval = attr[k];            }            var all = null;            if(id !== ""){                //获取某个id下的全部tag元素                all = document.getElementById(id).getElementsByTagName(tag);            }            else{                all = document.getElementsByTagName(tag);            }            for(var i = 0,len = all.length; i < len; i++) {                var obj = all[i];                if(obj.getAttribute(key) === aval){                    //保存匹配的dom                    dom.push(obj);                }            }            return dom;        }        var dom = null;        //获取传入参数的个数        var len = arguments.length;        switch(len){            case 1:                //如果只传了一个参数,那么符合只根据 id 查找                //我们直接通过getElementById()获取dom                dom = document.getElementById(arguments[0]);            break;            case 2:                //如果传了两个参数,那么符合 id + tag                //我们知道js是支持获取全部文档指定tag的元素,                //所以当id传入空串的时候,就能满足这种情况.(但是这种效率是低下的,可以根据实际情况是否需要必须指定id)                //ok,先判断id是否有值                var id = arguments[0] || "";                var tag = arguments[1] || "";                if(id !== "" && tag !== ""){                    dom = document.getElementById(id).getElementsByTagName(tag);                }                else{                    if(tag !== ""){                        dom = document.getElementsByTagName(tag);                    }                    else{                        //都传入空值不合法                    }                }            case 3:                //如果三个参数都有,就比较复杂了,我们列举一下.                // id + tag + attr                // "" + tag + attr                // "" + "" + attr(只能是name)                // id + "" + attr(这种是不成立的,因为id唯一)                //但是数学的排列组合不是这样的,还有 "" + tag + ""                //我们细想一下,这样就应该只传入两个参数呀                var id = arguments[0] || "";                var tag = arguments[1] || "";                //属性值都是key=value,所以第三个参数应该对象                var attr = arguments[2] || {};                if(id !== ""){                    if(tag !== "" && attr !== ""){                        // id + tag + attr                        dom = [];                        //获取dom元素                        dom = getbytag(id,tag,attr);                    }                    else{                        //不应该成立情况                        // id + tag + "" (应该只传入两个参数)                        // id + "" + attr(这种是不成立的,因为id唯一)                    }                }                else{                    if(tag !== ""){                        // "" + tag + attr                        dom = [];                        //获取dom元素                        dom = getbytag(id,tag,attr);                    }                    else{                        // "" + "" + attr(只能是name)                        //js只提供了getElementByName的接口,所以不能直接获取其它属性值的dom                        //如果要获取其它属性值的dom,只能采用 tag + attr                        dom = [];                        //属性                        var key = null;                        //属性值                        var aval = null;                        //解析attr                        for(var k in attr){                            key = k;                            aval = attr[k];                        }                        if(key === "name"){                            dom = document.getElementsByName(aval);                        }                        else{                            //参数不合法                        }                    }                }            break;        }        return dom;    }    //id    var dom = getDom("btn1");    console.log(dom.value);//mybtn1    //id + tag    var dom = getDom("mydiv","input");    for(var i in dom){        console.log(dom[i].value);//mybtn3,mybtn4    }    // "" + tag    var dom = getDom("","input");    for(var i in dom){        console.log(dom[i].value);//mybtn1,mybtn2,mybtn3,mybtn4    }    //id + tag + attr    var dom = getDom("mydiv","input",{"data":"test"});    for(var i in dom){        console.log(dom[i].value);//mybtn3    }    // "" + tag + attr    var dom = getDom("","input",{"class":"btn1"});    for(var i in dom){        console.log(dom[i].value);//mybtn1,mybtn2    }    // "" + "" + attr(只能是name)    var dom = getDom("","",{"name":"btn1"});    for(var i = 0,len = dom.length; i < len; i++){        console.log(dom[i].value);//mybtn2    }    /*    知识点:    getAttribute,这个是获取dom对象的属性方法.对应的设置一个属性就是setAttribute.    arguments,这是个很神奇的东西,它是js里面一个特殊的对象,有length属性,但它却不是数组.    它是函数接收参数的副本,调用函数的时候传入了多少个参数,length就是几,跟函数接收几个参数无关哦.    细细回味一下,动态参数个数,这泥马不是面向对象中的多态嘛.呵呵.你说是就是吧.    */</script>