getElementsByTagName不是document的专利

作者 happyWang 日期 2013-03-17 浏览量
getElementsByTagName不是document的专利

一直以来,但凡涉及到getElementById,getElementsByTagName,总是会习惯性的在前面加上document对象。就像昨天写的一个博客里面,有个关于清空指定id的后代节点中input type=”text”的内容的函数(传送门)。当我通过document.getElementById()获取指定的ID的对象之后,就开始很傻的一步步的遍历每个节点,看它是不是input type=“text”的;还看改节点有没有子节点,有的话,有几个,然后再考虑是否遍历查找。

代码如下:

/**
* [clearUserInput 根据元素的ID找到其子节点(包括子节点的子节点)
中的input元素并且type=”text”,将其value设为空]
* @param {[type]} id [DOM对象或者字符串表示元素的id值]
* @return {[type]} [description]
*/
function clearUserInput(id){
//参数校验
if(id === undefined){consoloe.log(“参数必须”);return 1;}//判断参数是否存在
id = ((typeof id) === “object”)?id:document.getElementById(id);//获取对象
if(id === null){consoloe.log(“未知对象”); return 2;}//typeof null === “object”

 var childrens = id.childNodes,len=childrens.length; i=0;
 for(i;i<len;i++){
     if(childrens\[i\] === undefined){return;}//到达边界
     if(childrens\[i\].nodeType === 3){continue;}
     if(childrens\[i\].childNodes.length !== 0){
         arguments.callee(childrens\[i\]);//循环遍历        
     }
     if(childrens\[i\].nodeName === "INPUT" && childrens\[i\].type === "text"){
         childrens\[i\].value = "";//内容设为空
     }
 }

}

最后,功能上面实现了,可是每次点击清除的时候,整个浏览器和卡机了差不多…..遍历的计算次数太多了

后来我偶然一下突然想了,既然document对象有getElementsByTagName()之类的方法,那其他的节点和document对象理论上应该是没差的,那它们是不是也应该有这些方法?

我就测试了下,果然一个div对象是有getElementsByTagName()的方法,可是没有getElementById()的方法

元素类型

节点类型

元素

1

属性

2

文本

3

注释

8

文档

9

document.nodeType == 9 一般的HTML标签,如div,p等等,他们的DOM对象的nodeType == 1 就我所知的,nodeType == 1的DOM对象仅有getElementsByTagName()的方法

之后我根据这个修改了一下代码

/**
* [clearUserInput 根据元素的ID找到其子节点(包括子节点的子节点)中的input元素并且type=”text”,将其value设为空]
* @param {[type]} id [DOM对象或者字符串表示元素的id值]
* @return {[type]} [description]
*/
function clearUserInput(id){
//参数校验

 //判断参数是否存在
 if(id === undefined){return 1;}
 //获取对象
 id = ((typeof id) === "object")?id:document.getElementById(id);
 //typeof null === "object"
 if(id === null){return 2;}
 //找到后代节点中的所有input标签
 var inputs = id.getElementsByTagName("input"),
 len=inputs.length, i=0;
 for(i;i<len;i++){
     //到达边界
     if(inputs\[i\] === undefined){return 3;}
     if(inputs\[i\].nodeName === "INPUT" && inputs\[i\].type === "text"){
         inputs\[i\].value = "";//内容设为空
     }
 }

}

效率果然显著提升