getElementsByTagName不是document的专利

一说到getElementsByTagName,我们总是第一时间想到document.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 = "";//内容设为空
         }
     }
 }

效率果然显著提升

作者: happyWang

Hello, the beautiful world

《getElementsByTagName不是document的专利》有1个想法

  1. Pingback: yEcErjeB

发表评论