zoukankan      html  css  js  c++  java
  • NodeList类数组对象: HTMLCollection , NamedNodeMap,两套API(childNodes , children)

    快捷键:leishuzuduixiang(类数组对象)  bianlijiedian(遍历节点)  jiedian(节点)  htmlcollection , namednodemap , nodelist。

    nodeList类数组对象的特点
    1,nodeList是一种类数组对象,用于保存一组有序的节点。
    2,通过方括号来访问nodeList的值,有item方法与length属性。
    3,它并不是Array的实例,没有数组对象的方法
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="js/domready.js"></script><!--必须导入该文件,搜狗输入domready.js-->
    <script>
    myReady(function(){
    var div=document.getElementById('div');//获取div对象
    console.log(div.childNodes);
    //获得节点列表(nodeList),这是属于操作DOM第一套API,所以会计算空文本节点,
    //(google chrome)显示:NodeList(5) [text, ul#ul1, text, ul#ul2, text] text表示空文本节点
    //(firefox)显示:NodeList(5) [ #text, ul#ul1, #text, ul#ul2, #text ] #text表示空文本节点
    //console.log(div.childNodes[0]);//通过方括号获取对象,显示:获取第一个nodeList对象 #text(空文本节点)
    //console.log(div.childNodes[3]);//通过方括号获取对象,如:第三个对象 ul#ul2

    var ul=document.getElementById("ul1");//获取ul对象
    var nodeList=ul.childNodes;//获得ul下面的所有子节点对象列表 nodeList并不是一个数据类型,而是一个类数组对象,即多个对象的集合,但不是数组。
    //alert(typeof nodeList);//返回的是 Object类型。
    /**
    * 把nodeList转化为数组对象 可以兼容IE5以上,兼容性很好。
    * @param {object} nodeList 获取所有子元素对象列表
    * @return {array} [返回数组对象]
    */
    function markArray(nodeList){//把nodeList转换成数组
    /*var arr=new Array();//创建新数组存放nodeList
    for (var i = 0; i < nodeList.length; i++) {
    arr[i]=nodeList[i];//把nodelist存放到数组中。
    }
    return arr;//返回数组*/


    /**如果不考虑IE8及以下,这个方法是最好的
    * 非常高效的把nodeList转化为数组对象 IE8以及IE8以下不兼容
    * @param {object} nodeList 获取所有子节点列表对象
    * @return {Array} 返回数组对象
    */
    function markArray(nodeList){//可以直接把nodeList直接转换成Array数组。
    return Array.prototype.slice.call(nodeList);//可以直接把nodeList直接转换成Array数组。
    }

    //这个方法最好,通用方法:
    var arr=null;//用于存放对象的变量,一般都给赋值null。其他可以赋值为""。
    try{
    return Array.prototype.slice.call(nodeList);//可以直接把nodeList直接转换成Array数组。IE8以及IE8以下不兼容
    }catch(e){
    arr=new Array();//不要定义在不需要的作用域。
    for (var i = 0; i < nodeList.length; i++) {//可以兼容IE7以上,兼容性很好。
    arr.push(nodeList[i]);//等于 arr[i]=nodeList[i]
    }
    return arr;
    }
    }
    var newarray=markArray(nodeList);//把nodeList转换成数组,
    //console.log(markArray(nodeList));//输出数组对象:Array(7) [ #text, li#oneLi, #text, li#twoLi, #text, li#threeLi, #text ],查看是不是数组,可以在控制台点击,查看prototype(原型)这个属性:Array
    newarray.push("<h1>You are my sumshime!</h1>");//添加对象,返回的是数组的长度,而不是数组本身。
    console.log(newarray);//返回数组:(8) [text, li#oneLi, text, li#twoLi, text, li#threeLi, text, "<h1>You are my sumshime!</h1>"] 。h1这个节点只是被添加到newarray数组中,并没有添加到dom树中去。
    })
    </script>
    </head>
    <body id="body">
    <div id="div">
    <ul id="ul1">
    <li id="oneLi"><a href="">1111</a><a href="" id="onea">22222</a><span id="span1"> </span> <span id="span2"></span></li>
    <li id="twoLi"><a href="">4444</a><a href="" >5555</a><a href="">6666</a></li>
    <li id="threeLi"><a href="">7777</a><a href="" >8888</a><a href="">9999</a></li>
    </ul>
    <ul id="ul2">
    <li></li>
    <li></li>
    <li></li>
    </ul>
    </div>
    </body>

    ============

    HTMLCollection NamedNodeMap 两个类数组对象
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="js/domready.js"></script><!--必须导入该文件,搜狗输入domready.js-->
    <script>
    myReady(function(){
    //以下是HTMLCollection类数组对象//
    //var scripts=document.scripts;
    //console.log(scripts);//返回:HTMLCollection(2) [script, script]
    //var links=document.links;
    //console.log(links);//返回:HTMLCollection(10) [a, a#onea, a, a, a, a, a, a, a, a, onea: a#onea]
    //var images=document.images;
    //console.log(images);//返回:HTMLCollection(2) [img, img]
    //var forms=document.forms;
    //console.log(forms);//返回:HTMLCollection(2) [form, form]
    //var cells=document.getElementById("tr").cells;//获取指定tr下面的所有单元格
    //console.log(cells);//返回:HTMLCollection(3) [td, td, td](火狐)
    //var options=document.getElementById("city").options;//获取指定下拉列表下所有的选项
    //console.log(options);//返回:HTMLOptionsCollection(5) [option, option, option, option, option, selectedIndex: 0]
    //var ps=document.getElementsByTagName("p");//获取文档结构中所有的p标签
    //console.log(ps);//返回:HTMLCollection(3) [p, p, p]

    //var cells=document.getElementById("tr").cells;
    //console.log(cells);//返回HTMLCollection类数组对象:HTMLCollection(3) [td#td, td, td, td: td#td](谷歌)
    //console.log(cells.length);
    //console.log(cells.item(2));
    //console.log(cells.item(3));//超过类数组对象的长度时,显示为null
    //console.log(cells.namedItem("td"));//返回 cells 类数组中先查找 id="td"的cell对象,如不存在,则查找name="td"的cell对象,如果存在多个name="td",则返回第一个。如果两个都不存在,则返回null对象。
    //=================以上是HTMLCollection类数组对象======================

     //NodeList是节点的集合,HTMLCollection是元素节点的集合,NamedNodeMap是特性节点的集合(所有属性的集合attributes),它们都是类数组对象

    //=================以下是NamedNodeMap类数组对象======================
    // var box=document.getElementById("tab");//获取table对象
    // box.setAttribute("name","two");//设置box对象的属性及属性值。
    // console.log(box);//所有属性都可以在火狐浏览器中查看,chrome浏览器只显示该对象(包括子节点和孙子节点)
    // var attributes=box.attributes;//获得box对象的所有属性。
    // console.log(attributes);//返回的是NamedNodeMap(box属性的集合)
    // console.log(attributes.length);//返回box对象属性集合中的长度
    // console.log(attributes.style);//返回box对象属性集合中的样式
    // console.log(attributes.item(0));//返回box对象属性集合中的第一个属性
    // console.log(attributes.item(1));//返回box对象属性集合中的第二个属性
    // console.log(attributes.getNamedItem("style"));//获取指定属性的值。
    // console.log(attributes.removeNamedItem("style"));//删除指定属性,页面内的样式就会消失

    //=================HTMLCollection类数组对象创建节点实例======================
    var ps=document.getElementsByTagName("p");//获得HTMLCollection类数组对象
    var length=ps.length;
    alert(length);
    var i=0;
    while (i<length) {//这里不能写i=ps.length,(死循环),因为HTMLCollection类数组对象活的,每当文档结构发生变化时,都会进行更新。HTMLCollection,NamedNodeMap,NodeList
    var a=document.createElement("p");
    var txt=document.createTextNode("<h1>you are my sumshime"+i);
    a.appendChild(txt);
    document.getElementById("div").appendChild(a);
    i++;
    }

    })
    </script>
    </head>
    <body id="body">
    <div id="div">
    <ul id="ul1">
    <li id="oneLi"><a href="">1111</a><a href="" id="onea">22222</a><span id="span1"> </span> <span id="span2"></span></li>
    <li id="twoLi" name="oneLi"><a href="">4444</a><a href="" >5555</a><a href="">6666</a></li>
    <li id="threeLi"><a href="">7777</a><a href="" >8888</a><a href="">9999</a></li>
    </ul>
    <table id="tab" style="border: 1px solid #333;background-color: #fof; display:block;">
    <tr id="tr1" name="tr1">
    <td id="td">table</td>
    <td name="td">table1</td>
    <td name="td">table2</td>
    </tr>
    <tr id="tr2">
    <td>table</td>
    <td>table</td>
    <td>table</td>
    </tr>
    </table>
    <img src="" alt="" style="display: block; border: 1px solid; 100px; height: 100px; background-color: #f00;"><img src="" alt="" style="display: block; border: 1px solid; 100px; height: 100px; background-color: #00f;">
    <form action="">
    姓名:<input type="text" name="name" value="张三">
    <input type="button" name="submit" value="提交">
    </form>
    <form action="">
    地址:<input type="text" name="address" value="中国">
    <input type="button" name="submit" value="提交">
    </form>
    <a href=""></a><a href=""></a>
    <select name="city" id="city">
    <option value="0">北京</option>
    <option value="1">上海</option>
    <option value="2">深圳</option>
    <option value="3">重庆</option>
    <option value="4">厦门</option>
    </select>
    <p>基础挤出机会</p>
    <p>基础挤出机会</p>
    <p>基础挤出机会</p>
    </div>
    </body>

    =====================================

    使用childNodes childElementCount
    //=====以下是第一种操作DOM的API,会把空文本节点计算在内。相比下面的第二套API兼容性会好点======
    //在控制台获取对象时:点击所获取的对象在firefox中显示各种属性,在chrome中是显示其子元素以及孙子元素的所有内容。
    DOM节点操作,标签之间的换行空文本节点在IE浏览器和firefox火狐浏览器中会读取,其他浏览器不会读取,需要兼容性方法,见搜狗:遍历节点
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="js/domready.js"></script><!--必须导入该文件,搜狗输入domready.js-->
    <script>
    //----------------这里获得的所有对象都是可以点开查看各种属性----------------
    myReady(function(){
    var ul=document.getElementById('ul1');
    var li1=document.getElementById("one");
    var li2=document.getElementById("two");
    var li3=document.getElementById("three");
    console.log(document.childNodes);//返回NodeList类数组对象,即文档结构下的所有子节点
    //console.log(document.childNodes[0]);//获取文档第一个子节点:<!DOCTYPE html>对象 ,点开可以看到各种属性及属性值(火狐),在谷歌中显示的是:所获取对象下面的所有子元素内容。
    //console.log(document.firstChild);//获取文档第一个子节点:<!DOCTYPE html>对象 ,点开可以看到各种属性及属性值(火狐),在谷歌中显示的是:所获取对象下面的所有子元素内容。
    //console.log(document.childNodes.item(0));//获取文档第一个子节点:<!DOCTYPE html>对象 ,点开可以看到各种属性及属性值(火狐),在谷歌中显示的是:所获取对象下面的所有子元素内容。
    //console.log(document.childNodes[0].tagName);//获取文档第一个子节点:<!DOCTYPE html>对象的标签名称:undefined
    //console.log(document.firstChild.tagName);//获取文档第一个子节点:<!DOCTYPE html>对象的标签名称:undefined

    //console.log(document.documentElement);//文档根节点:html对象,点开可以看到各种属性及属性值
    //console.log(document.documentElement.tagName);//html标签名称

    //console.log(document.documentElement.firstChild);//获取HTML的第一个子节点:head对象,点开可以看到各种属性及属性值(火狐),在谷歌中显示的是:所获取对象下面的所有子元素内容。
    //console.log(document.documentElement.lastChild);//获取HTML的最后一个子节点:body对象,点开可以看到各种属性及属性值(火狐),在谷歌中显示的是:所获取对象下面的所有子元素内容。
    //console.log(document.documentElement.firstChild.tagName);//获取HTML的第一个子节点的标签名称:head
    //console.log(document.documentElement.lastChild.tagName);//获取HTML的最后一个子节点的标签名称:body

    var ul=document.getElementById("ul1");
    //获得第一个和最后一个子节点有三种方式:
    //console.log(ul.firstChild);//空文本子节点
    //console.log(ul.childNodes[0]);//空文本子节点
    //console.log(ul.childNodes.item(0));//空文本子节点

    var ul=document.getElementById("ul1");
    //获得除了第一个和最后一个之外的节点有两种方式:
    //console.log(ul.childNodes[1]);
    //console.log(ul.childNodes.item(1));

    var li=document.getElementById("twoLi");//获取li对象
    //console.log(li.tagName);//获得li标签的名称
    //console.log(li.nextSibling);//因为下面每个li都有换行,所以左右兄弟节都是空文本节点,所以这里显示:#text,谨记。
    //console.log(li.previousSibling);//因为下面每个li都有换行,所以左右兄弟节都是空文本节点,所以这里显示:#text,谨记。

    var a=document.getElementById("onea");//获取a对象
    //console.log(a.nextSibling);//获取下一个兄弟对象: <span>333</span>
    //console.log(a.previousSibling);//获取上一个兄弟对象: <a href="">1111</a>

    var ul=document.getElementById("ul1");//获取ul对象
    var a=document.getElementById("onea");//获取a对象
    //console.log(ul.parentNode);//获得父节点 div
    //console.log(a.parentNode);//获得父节点 li

    var ul=document.getElementById("ul1");//获取ul对象
    var a=document.getElementById("onea");//获取a对象
    //console.log(ul.ownerDocument===document);
    //console.log(ul.ownerDocument===document);
    //console.log(document);//显示:HTMLDocument file:///D:/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/HTML/%E4%BD%9C%E4%B8%9A%E7%B4%A0%E6%9D%90/textTwo.html 表示获取该文件的绝对路径。

    var ul=document.getElementById("ul1");//获取ul对象
    var a=document.getElementById("onea");//获取a对象
    var span1=document.getElementById("span1");//获取span对象
    var span2=document.getElementById("span2");//获取span对象
    //console.log(ul.hasChildNodes());//返回:true. 有3个li子节点
    //console.log(a.hasChildNodes());//返回:true. 有"2222"文本子节点
    //console.log(span1.hasChildNodes());//返回:true 有空文本子节点,即:有一个空格
    //console.log(span2.hasChildNodes());//返回:false 没有节点
    })
    </script>
    </head>
    <body id="body">
    <div id="div">
    <ul id="ul1">
    <li id="oneLi"><a href="">1111</a><a href="" id="onea">22222</a><span id="span1"> </span> <span id="span2"></span></li>
    <li id="twoLi"><a href="">4444</a><a href="" >5555</a><a href="">6666</a></li>
    <li id="threeLi"><a href="">7777</a><a href="" >8888</a><a href="">9999</a></li>
    </ul>
    <ul id="ul2">
    <li></li>
    <li></li>
    <li></li>
    </ul>
    </div>
    </body>

    //===========================以下是第二种操作DOM的API,忽略空文本节点。不兼容IE8及其以下=============================
    //在控制台获取对象时:点击所获取的对象在firefox中显示各种属性,在chrome中是显示其子元素以及孙子元素的所有内容。
    //第二套API是比较专门针对文本DOM节点进行开发的,所以每个属性都带有element(元素),除了children[i]
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="js/domready.js"></script><!--必须导入该文件,搜狗输入domready.js-->
    <script>

    myReady(function(){
    var div=document.getElementById('div');//获取div对象
    //console.log(div.childElementCount);//获取div的子节点个数,孙子节点不管。

    var ul1=document.getElementById("ul1");//获取ul1对象
    //console.log(ul1.firstElementChild);//获取第一个子元素,点击在FF中显示各种属性,在chrome中是显示其子元素以及孙子元素的所有内容。
    //console.log(ul1.lastElementChild);//获取最后一个子元素,点击在FF中显示各种属性,在chrome中是显示其子元素以及孙子元素的所有内容。

    var a=document.getElementById("onea");//获取a对象
    //console.log(a.nextElementSibling);//获取id=onea 标签的下一个兄弟元素
    //console.log(a.previousElementSibling);//获取id=onea 标签的前面一个兄弟元素

    var ul1=document.getElementById("ul1");//获取ul对象
    console.log(ul1.children[0]);//获取id=ul1的第一个子元素,忽略所有空文本节点
    console.log(ul1.children[1]);//获取id=ul1的第二个子元素,忽略所有空文本节点
    console.log(ul1.children[2]);//获取id=ul1的第三个子元素,忽略所有空文本节点
    })
    </script>
    </head>
    <body id="body">
    <div id="div">
    <ul id="ul1">
    <li id="oneLi"><a href="">1111</a><a href="" id="onea">22222</a><span id="span1"> </span> <span id="span2"></span></li>
    <li id="twoLi"><a href="">4444</a><a href="" >5555</a><a href="">6666</a></li>
    <li id="threeLi"><a href="">7777</a><a href="" >8888</a><a href="">9999</a></li>
    </ul>
    <ul id="ul2">
    <li></li>
    <li></li>
    <li></li>
    </ul>
    </div>
    </body>

    ======================

    =======以下是第一种 API 遍历方法 一 =======
    第一种API 遍历文本节点注重的是文本节点,忽略空的文本节点。兼容性比较好。
    遍历文档所有节点,并且打印出来
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="js/domready.js"></script><!--必须导入该文件,搜狗输入domready.js-->
    <script>
    myReady(function(){
    var s="";
    function travel(spance,node){
    debugger;
    if (node.tagName) {//判断当前节点是否是空标签,不是就添加html标签名称。
    s+=spance+node.tagName+"<br/>";
    }
    var len= node.childNodes.length;//获得所有子节点个数
    for (var i = 0; i < len; i++) {
    travel(spance+"|-",node.childNodes[i])
    }
    }
    travel("",document);
    document.write(s);
    })
    </script>
    <body>
    <div>
    <ul id="ul1">
    <li><a href="">111</a></li>
    <li><a href="">111</a></li>
    <li><a href="">111</a></li>
    </ul>
    <ul id="ul2">
    <li></li>
    <li></li>
    <li></li>
    </ul>
    </div>
    </body>

    -------替换上面,这是自己编写的,仅仅用于递归遍历所有节点名称---------
    myReady(function(){
    var str="";//存储打印在文档的字符串
    /**
    * 递归查找文本所有节点名称
    * @param {标签对象} node 标签
    * @return {string} 打印的文本
    */
    function travel(node){
    if (node.nodeType==1) {//node.nodeType==1,则不为空;node.nodeType==0,则返回空。
    str+=node.tagName+"--";//读取每个节点的名称,这个递归需要做的只有读取节点名称
    }
    for (var i = 0; i < node.childNodes.length; i++) {//遍历当前节点的所有子节点
    travel(node.childNodes[i]);//所有子节点进行递归
    }
    }
    travel(document);//document是当前文档:从html开始。
    document.write(str);//打印字符串
    })
    -------------------------------------
    重点:node.nodeType==1,表示非空节点,node.nodeType==0,表示空文本节点(换行)
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>节点遍历</title>
    <script src="js/domready.js"></script><!--必须导入该文件,搜狗输入domready.js-->
    <script>
    myReady(function(){
    var p=document.getElementById('p');//获取div对象
    for (var i=0,len=p.childNodes.length; i<len; i++) {//声明两个变量可以用逗号分开

    //node.nodeType==1,表示非空节点,node.nodeType==0,表示空文本节点(换行)
    //如果没有进行if判断,直接输出:console.log(p.childNodes[i]); 控制台显示:#text <span> #text <span> #text <span> #text。
    //总共7个对象,四个#text(空文本节点),所以要使用node.nodeType==1,筛选出非空节点进行输出。
    if (p.childNodes[i].nodeType==1) {
    debugger;
    //console.log(p.childNodes[i]);//这两句话分开打印。获取标签对象。
    document.write(p.childNodes[i].tagName+"<br/>");//这两句话分开打印。获取标签的名称。
    }
    }
    });
    </script>
    </head>
    <body>
    <p id="p">
    <span>
    <a href=""></a>
    <a href=""></a>
    <a href=""></a>
    </span>
    <span>
    <a href=""></a>
    <a href=""></a>
    <a href=""></a>
    </span>
    <span>
    <a href=""></a>
    <a href=""></a>
    <a href=""></a>
    </span>
    </p>
    </div>
    </body>
    </html>
    --------------------
    第一种API 遍历文本节点注重的是所有DOM节点,包括空的文本节点。兼容性比较好。

    =======以上是第一种 API 遍历方法 一 =======


    =======以下是第二种 API 遍历方法 一 =======
    第二套API是比较专门针对文本DOM节点进行开发的,所以每个属性都带有element(元素),除了children[i]

    第二种API 遍历文本节点注重的是标签对象节点,忽略空的文本节点。兼容性相对差一点,IE8以及IE8以下不支持,其他浏览器兼容性比较好。
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="js/domready.js"></script><!--必须导入该文件,搜狗输入domready.js-->
    <script>
    myReady(function(){
    var ul=document.getElementById('ul1');//获取对象
    for (var i=0,len=ul.childElementCount; i<len; i++) {//遍历对象下面的所有子节点,空文本节点忽略(换行)
    console.log(ul.children[i]);//输出子节点名称,这两个输出要分开,否则只能显示一个。
    //document.write(ul.children[i].tagName+"<br/>");//输出子节点名称,这两个输出要分开,否则只能显示一个。
    }
    })
    </script>
    <body>
    <div>
    <ul id="ul1">
    <li><a href="">111</a></li>
    <li><a href="">111</a></li>
    <li><a href="">111</a></li>
    </ul>
    <ul id="ul2">
    <li></li>
    <li></li>
    <li></li>
    </ul>
    </div>
    </body>
    ============================

  • 相关阅读:
    什么是多线程中的上下文切换?
    什么是基本表?什么是视图?
    什么是存储过程?用什么来调用?
    随意写文件命令?怎么向屏幕输出带空格的字符串,比如” hello world”?
    NULL 是什么意思 ?
    Mock 或 Stub 有什么区别?
    什么叫视图?游标是什么?
    什么是微服务中的反应性扩展?
    什么是线程组,为什么在 Java 中不推荐使用?
    Java 中用到的线程调度算法是什么?
  • 原文地址:https://www.cnblogs.com/Knowledge-is-infinite/p/10883699.html
Copyright © 2011-2022 走看看