zoukankan      html  css  js  c++  java
  • jacascript DOM节点——元素节点、属性节点、文本节点

    前言:这是笔者学习之后自己的理解与整理。如果有错误或者疑问的地方,请大家指正,我会持续更新!

       DOM节点的三个种类:元素节点、文本节点、属性节点;

    元素节点

      元素节点就是 HTML 标签元素,元素节点主要提供了对元素标签名、子节点及属性的访问;

      元素节点的三个node属性:nodeType:1、nodeName/TagName:元素的标签名大写、nodeValue:null(一般用在文本节点和属性节点)

      obj.nodeType 表示节点类型,有两种表示方法:数值或大写英文;但数值有兼容性问题,推荐用大写英文,字面好理解并且现在大家不都是有代码提示;

      document.createElement("element"); 创建一个元素节点

      DOM节点——节点获取

      DOM节点——节点关系与操作

      DOM节点——节点内容

      元素节点有一个非标准的属性 innerHTML,虽然非标准,但都支持它;(以文本形式返回元素节点里的内容,包括标签),它还可以赋值(这时候包含的标签,可以被解析);

      元素节点还提供了一些 HTML 属性的属性,id、title、style(仅行内样式)、className 等;

            <div id="testId" class="testClass" style="color:red;" title="testTitle">
                hello <span style="color: green;">world</span>
            </div>
            <script type="text/javascript">
                var oTest = document.getElementById('testId');
                console.log(oTest.nodeType);//1
                console.log(oTest.tagName);//DIV
                console.log(oTest.nodeValue);//null   
                console.log(oTest.innerHTML);//hello <span style="color: green;">world</span>
                
                console.log(oTest.id);//testId
                console.log(oTest.style);//CSSStyleDeclaration{...}
                console.log(oTest.style.color);//red
                console.log(oTest.className);//testClass
                console.log(oTest.title);//testTitle
            </script>

      操作属性的方法主要有 hasAttribute()、getAttribute()、setAttribute()、removeAttribute() 四个,可以针对任何属性使用,包括那些自定义的属性;

    hasAttribute

      obj.hasAttribute(attr) 方法,attr 直接写,不必考虑关键字之类的,返回一个布尔值,表示当前元素节点是否包含指定属性;IE6/IE7不支持 hasAttribute() 方法

    • obj.hasAttribute(attr) 检测 class 属性时,直接用 class 就可以了,不要用 className;
    • obj.hasAttribute(attr) 检测 for 属性时,直接用 for 就可以了,不要用 htmlFor;
            <div class="wrapper" id='test' for="nice" style="200px;height:100px;background:#f0f">123</div>
            
            <script type="text/javascript">
                var oTest = document.getElementById('test');
                //IE6/IE7不支持hasAttribute方法
                console.log(oTest.hasAttribute('class'));//true
                console.log(oTest.hasAttribute('className'));//false   
                console.log(oTest.hasAttribute('id'));//true
                console.log(oTest.hasAttribute('style'));//true
                console.log(oTest.hasAttribute('for'));//true
                console.log(oTest.hasAttribute('htmlFor'));//false
            </script>

    getAttribute

      obj.getAttribute(attr) 方法用于取得属性的值,如果给定名称的属性不存在或无参数则返回null;此方法兼容性不是很好,我们应该竟可能避免使用此方法操作 Html 属性

    • obj.getAttribute(attr) 获取 class 时,直接用 class 就可以了;IE6/IE7除外,IE6/IE7的 getAttribute(attr) 方法要用 className
    • 我们获取 class 时,可以直接 obj.className 就行了,兼容性都不必考虑
    • obj.getAttribute(attr) 获取 for时,直接用 for就可以了;
            <div class="wrapper" id='test' for="nice" style="200px;height:100px;background:#f0f">测试</div>
            
            <script type="text/javascript">
                var oTest = document.getElementById('test');
                console.log(oTest.getAttribute('class'));//wrapper
                console.log(oTest.getAttribute('className'));//null   
                
                console.log(oTest.getAttribute('id'));//test
                console.log(oTest.getAttribute('style'));//200px;height:100px;background:#f0f
                console.log(oTest.getAttribute('for'));//nice
            </script>

    setAttribute

      obj.setAttribute(attr,value)方法接受两个参数:要设置的属性名和值,如果已经存在,则替换现有的值。如果属性不存在,则创建该属性并设置相应的值。该方法无返回值;

    • obj.setAttribute(attr,value)设置 class 时,直接用 class 就可以了;
    • obj.setAttribute(attr,value)设置 for 时,直接用 for 就可以了;
    • obj.setAttribute(attr,value)设置 style 时,直接用 style 就可以了;在 IE7及以下,用 obj.style.setAttribute("cssText",value);  这里的 style 只是行间样式;我们一般用 window.getComputedStyle ? getComputedStyle(obj)[attr] : obj.currentStyle[attr]; 来获取元素当前计算样式;
            <script type="text/javascript">
                var oTest = document.getElementById('test');
                oTest.setAttribute('class','aaa'); //setAttribute直接用class就可以了
                console.log(oTest.class);//undefined  IE8及以下会报错缺少标识符
                console.log(oTest.getAttribute('class'));//aaa  getAttribute直接用class就可以了
                console.log(oTest.className);//aaa
                
                oTest.setAttribute('style','border:1px solid red;height: 100px;'); //setAttribute直接用 style 就可以了
                console.log(oTest.style);//所有的style设置,包括你没有设置的,太多了,肯定不是你想要的
                console.log(oTest.getAttribute('style'));
                //border:1px solid red;height: 100px;  getAttribute直接用 style 就可以了
                
                oTest.setAttribute('for','eee'); //setAttribute直接用for就可以了
                console.log(oTest.getAttribute('for'));//eee  getAttribute直接用for就可以了
            </script>

    removeAttribute

      obj.removeAttribute(attr)方法用于彻底删除元素的属性,这个方法不仅会彻底删除元素的属性值,还会删除元素属性。该方法无返回值;IE6及以不支持这个方法

            <div class="wrapper" id='test' for="nice" style="background:#f0f;height: 100px;">123</div>
            <script type="text/javascript">
                var oTest = document.getElementById('test');
                oTest.removeAttribute('class'); //removeAttribute直接用class就可以了
                oTest.removeAttribute('for');
                oTest.removeAttribute('style'); 
                console.log(oTest);// <div id="test">123</div>
            </script>

      其父节点 parentNode 指向包含该元素节点的元素节点 Element 或文档节点 Document;

      元素的 childNodes 属性中包含了它的所有子节点,这些子节点可能是元素、文本、注释、处理指令节点;

      childNodes 结合 NodeType 可以检查有几个元素子节点:

            <ul class="list" id="list">
                <li class="in"></li>
                <li class="in"></li>
            </ul>
            <script>
                var oList = document.getElementById('list');
                var children = oList.childNodes;
                var num = 0;
                for(var i = 0; i < children.length; i++){
                    if(children[i].nodeType == 1){
                        num++;
                    }
                }
                console.log(num);//2   有2个元素子节点   
            </script>

      

    属性节点

      属性节点,有的叫特性节点,差不多一个意思;属性节点的三个node属性,nodeType:2、nodeName/name:属性名称、nodeValue/value:属性值;

      属性节点还有一个 specified 属性,specified 是一个布尔值,用以区别特性是在代码中指定的,还是默认的。这个属性的值如果为true,则意味着在HTML中指定了相应特性,或者是通过 setAttribute() 方法设置了该属性。在IE中,所有未设置过的特性的该属性值都为false,而在其他浏览器中,所有设置过的特性的该属性值都是true,未设置过的特性,如果强行为其设置 specified 属性,则报错。

      元素节点有一个 attributes 属性,它包含一个 NamedNodeMap,包含当前元素所有的属性及属性值,与 NodeList 类似,也是一个动态的集合。元素的每一个属性都由一个Attr节点表示,每个节点都保存在 NamedNodeMap 对象中,每个节点的 nodeName 就是属性的名称,节点的 nodeValue 就是属性的值;

      document.createAttribute("attr") 创建新的属性节点

      attributes属性包含以下四个方法:

    1. obj.attributes.setNamedItem(attr);  向列表中添加节点,该方法无返回值;要先创建属性,在以 nodeValue 的形式赋属性值,在传入 setNamedItem
    2. obj.attributes.getNamedItem(attr);  返回 nodeName 属性等于 attr 的节点;以" attr=value " 形式返回;
    3. obj.attributes.removeNamedItem(attr); 从列表中移除 nodeName 属性等于 attr 的节点,并返回该节点;
    4. obj.attributes.item(index); 返回位于下标 index 位置处的节点,也可以用[]代替, obj.attributes[index];
            <div class="wrapper" id='test' for="nice" style="background:#f0f;height: 100px;">123</div>
            <script type="text/javascript">
                var oTest = document.getElementById('test');
                console.log(oTest.attributes);// NamedNodeMap {0: class, 1: id, 2: for, 3: style, length: 4}
                console.log(oTest.attributes.item(1).specified);//true
    console.log(oTest.attributes.getNamedItem(
    'id'));//id='test' console.log(typeof oTest.attributes.getNamedItem('id'));//object console.log(oTest.attributes.removeNamedItem('for'));//id='test' console.log(oTest.attributes);// NamedNodeMap {0: class, 1: id, 2: style, length: 3} var abc = document.createAttribute("abc"); abc.nodeValue = "1234567"; oTest.attributes.setNamedItem(abc); //obj.attributes.setNamedItem(attr) 要先创建属性,在以nodeValue的形式赋属性值,在传入setNamedItem console.log(oTest.attributes);// NamedNodeMap {0: class, 1: id, 2: style, 3: abc, length: 4} console.log(oTest.attributes.item(1));//id='test' console.log(oTest.attributes[1]);//id='test' </script>

      attributes属性主要用于属性遍历。在需要将DOM结构序列化为HTML字符串时,多数都会涉及遍历元素特性

            <div class="wrapper" id='test' for="nice" style="background:#f0f;height: 100px;">123</div>
            <script type="text/javascript">
                function outputAttributes(obj){
                    var arr = [],
                        attrName,
                        attrValue,
                        i;
                    for(i = 0; i < obj.attributes.length; i++){
                        attrName = obj.attributes[i].nodeName;
                        attrValue = obj.attributes[i].nodeValue;
                        arr.push(attrName + '="' + attrValue + '"');
                    }
                    return arr.join(" ");
                }
                
                var oTest = document.getElementById('test');
                console.log(oTest.attributes);//NamedNodeMap {0: class, 1: id, 2: for, 3: style, length: 4}
                console.log(typeof oTest.attributes);//object
                
                console.log(outputAttributes(oTest));
                //class="wrapper" id="test" for="nice" style="background:#f0f;height: 100px;"
                console.log(typeof outputAttributes(oTest));//string
            </script>

    文本节点

      文本节点的三个node属性,nodeType:3、nodeName:'#text'、nodeValue:节点所包含的文本,其父节点 parentNode 指向包含该文本节点的元素节点,文本节点没有子节点;

      关于文本节点,遇到最多的兼容问题是空白文本节点问题IE8及以下浏览器不识别空白文本节点,而其他浏览器会识别空白文本节点 ;所以有时候我们需要清理空白文本节点;

            <div id="test">
                <div>hello world!</div>
            </div>
            <script type="text/javascript">
                var oTest = document.getElementById('test');
                console.log(oTest.childNodes);//[text, div, text]    
                //标准浏览器输出[text, div, text],text表示空白文本节点
                //IE8及以下浏览器输出[div],并不包含空白文本节点
                console.log(oTest.childNodes.length); //3
                //标准浏览器返回3
                //IE8及以下浏览器返回1,并不包含空白文本节点
                
                //清理空白文本节点
                function removeWhiteSpace(oNode){
                     for(var i = 0; i < oNode.childNodes.length; i++){
                          if(oNode.childNodes[i].nodeType === 3 && /^s+$/.test(oNode.childNodes[i].nodeValue)){
                              oNode.childNodes[i].parentNode.removeChild(oNode.childNodes[i]);
                          }
                      }
                     return oNode;
                }
                console.log(removeWhiteSpace(oTest).childNodes);//[div]
                console.log(removeWhiteSpace(oTest).childNodes.length); //1
            </script>

    文本节点属性:

    • 文本节点的 data 属性与 nodeValue 属性相同
    • wholeText 属性将当前 Text 节点与毗邻的 Text 节点,作为一个整体返回。大多数情况下,wholeText 属性的返回值,与 data 属性和 textContent 属性相同;
    • 文本节点的 length 属性保存着节点字符的数目,而且 nodeValue.length、data.length 也保存着相同的值;
            <div id="testData">hello world!</div>
            <div id="testWholeText">hello world!</div>
            <script type="text/javascript">
                var oTestData = document.getElementById('testData');
                //第一个和最后一个都是空白文本节点
                console.log(oTestData.firstChild);//"hello world!"   
                console.log(typeof oTestData.firstChild);//object   
                console.log(oTestData.childNodes.length); //1
                
                console.log(oTestData.firstChild.nodeValue);//"hello world!" 
                console.log(typeof oTestData.firstChild.nodeValue);//string
                console.log(oTestData.firstChild.data);//"hello world!" 
                //文本节点的data属性与nodeValue属性相同,都是 string 类型
                console.log(oTestData.firstChild.data === oTestData.firstChild.nodeValue);//true
                
                var oTestWholeText = document.getElementById('testWholeText');
                console.log(oTestWholeText.childNodes); //[text]
                console.log(oTestWholeText.childNodes.length); //1
                console.log(oTestWholeText.firstChild.wholeText);//hello world!
                console.log(oTestWholeText.firstChild.data);//hello world!   
                
                oTestWholeText.firstChild.splitText('or');
                console.log(oTestWholeText.childNodes); //[text, text]
                console.log(oTestWholeText.childNodes.length); //2
                console.log(oTestWholeText.firstChild);//#text
                console.log(oTestWholeText.firstChild.wholeText);//hello world!
                //wholeText属性将当前Text节点与毗邻的Text节点,作为一个整体返回。
                
                console.log(oTestData.firstChild.length);//12
                console.log(oTestData.firstChild.nodeValue.length);//12
                console.log(oTestData.firstChild.data.length);//12
            </script>

    文本节点方法:

      文本节点的操作与字符串的操作方法相当类似。一般地,我们获取文本都用 innerHTML,然后再去字符串的操作方法去操作。

    • document.createTextNode("text"); 方法用于创建文本节点,这个方法接收一个参数,要插入节点中的文本插入的是文本,就算写的是标签,也是当做文本来插入的
    • normalize() 方法的作用是合并相邻的文本节点,该方法在文本节点的父节点上调用;IE9及以上浏览器不支持;
    • splitText(index) 方法将一个文本节点分成两个文本节点,即按照 index 指定的位置分割 nodeValue 值。原来的文本节点将包含从开始到指定位置之前的内容。这个方法会返回一个新文本节点,包含剩下的文本;
    • appendData(text) 方法将 text 添加到节点的末尾,该方法无返回值;
    • deleteData(index,count) 方法从 index指定的位置开始删除 count 个字符,无返回值;
    • insertData(index,text) 方法在 index 指定的位置插入 text,无返回值;
    • replaceData(index,count,text) 方法用 text 替换从 index 指定位置开始到 index+count 为止的文本,无返回值;
    • substringData(index,count) 方法提取从 index 指定的位置开始到 offset+count 为止处的字符串,并返回该字符串。原来的文本节点无变化;
  • 相关阅读:
    渗透测试学习 二十一、 JSP相关漏洞
    渗透测试学习 二十、 其他漏洞汇总之PHP相关漏洞
    渗透测试学习 十九、 XSS跨站脚本漏洞详解 续2
    渗透测试学习 十八、 XSS跨站脚本漏洞详解 续
    渗透测试学习 十七、 XSS跨站脚本漏洞详解
    渗透测试学习 十六、 常见编辑器漏洞解析
    渗透测试学习 十五、 文件上传&&解析漏洞
    渗透测试学习 十四、 脚本木马的制作与原理
    渗透测试学习 十三、 SQLmap使用详解
    渗透测试学习 十二、 其他注入漏洞汇总 续
  • 原文地址:https://www.cnblogs.com/sspeng/p/6680545.html
Copyright © 2011-2022 走看看