<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="mybtn1" /> <input name="btn1" class="btn1" type="button" value="mybtn2" /> <img src="" alt="img1" /> <img src="" alt="img2" /> <div id="mydiv"> <input class="btn2" type="button" data="test" value="mybtn3" /> <input class="btn2" type="button" value="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>
获取dom对象(4)
时间: 2024-10-14 04:20:35