javascript文档对象模型-Node 对象

作者: 鲁智深 分类: JAVASCRIPT 发布时间: 2016-01-02 01:18

获取父节点

通过 HTML 页面的指定标签查找其父节点,我们可以通过如下属性实现:

parentNode: 表示获取指定节点的父节点。一个元素节点的父节点可能是一个元素(Element )节点,也可能是一个文档(Document )节点。

parentElement: 表示获取当前节点的父元素节点。如果该元素没有父节点,或者父节点不是一个元素节点,则返回 null。

获取父节点

获取父节点

通过如下代码进行测试,对比两者之间的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>01获取父节点</title>
</head>
<body>
    <ul id="nodeid">
        <li>小米</li>
        <li id="chuizi">锤子</li>
        <li>华为</li>
    </ul>
    <script>
        //测试parentElement和parentNode的区别
        /*
            parentNode - 获取父节点
            父级节点可以是所有节点类型,包括文档节点
           
            parentElement - 获取父元素节点
            父级必须是元素节点 -> 其实就必须是HTML的标签
            <html>标签的父元素节点是null
        */

        //查询节点位置
        var nodeid = document.getElementById('chuizi');
        //获取父节点
        console.log(nodeid.parentElement);//获取了ul节点
        console.log(nodeid.parentNode);//获取了ul节点

        //在顶级元素节点上测试
        var html = document.documentElement;//属性可返回文档的根节点
        console.log(html.parentElement);//null
        console.log(html.parentNode);//#document文档节点

        //总结:如果获取的不是顶级元素节点的情况下,两者都是可以使用
        //parentElement匹配的是parent为element(元素)的情况,而parentNode匹配的则是parent为node(节点)的情况。
    </script>
</body>
</html>

原因在于 标签的父节点是文档节点。文档节点并不是一个元素节点,所以 parentElement 返回 null。

获取子节点存在空白节点(文本节点)

测试获取指定节点的子节点时,我们规定必须要在 IE 8 版本或之前的版本中运行,而不能在其他浏览器中运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>02获取子节点</title>
</head>
<body>
    <ul id="nodeid">
        <li>小米小米小米小米</li>
        <li id="chuizi">锤子</li>
        <li>华为</li>
    </ul>
    <script>
       //查询定位节点
       var nodeid = document.getElementById('nodeid');
       //通过父级获取子节点
       /*
          1、.firstChild:获取父级第一个子节点
        */

        console.log(nodeid.firstChild);//#text

        /*
          2、.childNodes获取id="parent"节点的所有子节点
        */

        console.log(nodeid.childNodes);//(7)[text, li, text, li#chuizi, text, li, text]
        //发现一个有趣的问题,父级节点的第一个子节点是个空白节点(#text,属于文本节点),获取所有li节点时
        //每一个li节点中间都会有空白节点(text),这是Dom树结构中空格换行导致的空节点
         
        //我需要去除text文本节点怎么办
        //先遍历在组合成数组
        var nodeLi = nodeid.childNodes;//获取所有li子节点
        var arr = [];
        var nodeidLength = nodeid.childNodes.length;//节点长度
        for(i = 0; i<nodeidLength;i++){
            console.log(nodeLi[i]);
            console.log(nodeLi[i].nodeType);//如何可以判断当前节点的类型--->知识点下图
            if(nodeLi[i].nodeType === 1){
              arr.push(nodeLi[i]);
            }
        }
        console.log(arr);//(3) [li, li#chuizi, li]
    </script>
</body>
</html>

谷歌浏览器运行情况

获取子节点

获取子节点

代码原因

空格换行导致Dom树结构的空节点

空格换行导致Dom树结构的空节点

有些浏览器在遍历 DOM 时,会在元素节点之间添加一个文本节点,不管这个文本节点的内容是否为空(即空白节点)。

文本节点

文本节点

不会自动添加空白节点的浏览器只有 IE 8 版本以及之前的版本。换句话讲,IE 9 及之后的版本、Chrome、Firefox 和 Safari 等浏览器都会自动添加空白节点。
这个问题的解决,可以通过 getElementsByTagName() 方法实现。

解决空白节点问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>解决空白节点问题</title>
    <script src="js/MyTool.js"></script>
</head>
<body>
<ul id="parent">
    <li>苹果</li>
    <li id="huawei">华为</li>
    <li>小米</li>
</ul>
<script>
    /*
     解决:获取空白标签的问题
     firstChild: 获取指定标签的第一个子节点。
     lastChild: 获取指定标签的最后一个子节点。
     childNodes: 获取指定标签的所有子节点。
     nextSibling: 获取指定节点的后一个兄弟节点。
     previousSibling: 获取指定节点的前一个兄弟节点。
    */

     var parent = document.getElementById('parent');

     console.log(firstChild(parent));
     console.log(lastChild(parent));
     console.log(childNodes(parent));
     console.log(nextSibling(huawei));
     console.log(previousSibling(huawei));
</script>
</body>
</html>

---------------------贴一个示例--------------------

//解决firstChild: 获取指定标签的第一个子节点。
function firstChild(parent){
    var Child = parent.firstChild;
        if(Child.nodeType === 3){
            Child = Child.nextSibling;
        }
        return Child;
}

插入节点

向 HTML 页面标签插入新的标签或者其他标签,我们可以通过如下方法实现。

appendChild(): 将一个节点添加到指定父节点的子节点列表末尾。

insertBefore(): 在当前节点的某个子节点之前再插入一个子节点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>04插入节点</title>
</head>
<body>
<ul id="parent">
    <li>苹果</li>
    <li id="mi">小米</li>
    <li id="xigua">西瓜</li>
</ul>
<script>
    /* parent.appendChild(newChild)方法 -> 将新节点添加到父节点的所有子节点列表的最后面
       向<ul>标签添加子节点 <li>香蕉</li> */

        var ul = document.getElementById('parent');//获取父节点
        var li = document.createElement('li');
        var text = document.createTextNode('香蕉');
        li.appendChild(text);
        ul.appendChild(li);

    /* 向id="mi"节点的前面添加一个新的兄弟节点
       parent.insertBefore(newChild, currentChild)方法 -> 将新节点添加指定节点的前面(前一个兄弟节点) */

        var mibro = document.getElementById('mi');
        var libro = document.createElement('li');
        var textbro = document.createTextNode('兄弟');
        libro.appendChild(textbro);
        ul.insertBefore(libro,mibro);
    /*  
       那么有没有,插入/添加后面节点 -> 没有insertAfter()方法
       JavaScript没有定义此方法,但是jQuery插件有这样的功能,不能混淆
    */

     
     // 自己创造一个,将新节点添加到指定节点的后面(后一个兄弟节点)
</script>
</body>
</html>

删除节点问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
parentNode.removeChild(childNode)从 HTML 页面中删除指定元素节点(标签)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>删除节点</title>
</head>
<body>
<ul id="parent">
    <li>苹果</li>
    <li id="child">小米</li>
    <li>锤子</li>
</ul>
<script>
      /*
        parentNode.removeChild(childNode)
      */

      var id = document.getElementById('parent');//获取父节点
      var child = document.getElementById('child');//获取要删除的子节点
      id.removeChild(child);
</script>
</body>
</html>

替换节点

parentNode.replaceChild(newChild,oldChild)将 HTML 页面中指定元素节点(标签)被替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>替换节点</title>
</head>
<body>
<ul id="phone">
    <li>苹果</li>
    <li id="mi">小米</li>
    <li id="chui">锤子</li>
</ul>
<ul id="game">
    <li>魔兽</li>
    <li id="wzry">王者荣耀</li>
    <li>绝地求生</li>
</ul>
<script>
     /*
       parentNode.replaceChild(newChild,oldChild)
     */

    //创建一个li节点
    var li = document.createElement('li');
    var text = document.createTextNode('添加了大鹏');
    li.appendChild(text);
   
    var phone = document.getElementById('phone');//找到父节点
    var mi = document.getElementById('mi');//找到要替换的节点
    phone.replaceChild(li,mi);//替换

     /*
       锤子替换下面的王者荣耀
     */

    var chui = document.getElementById('chui');
    var phone = document.getElementById('game');//找到父节点
    var wzry = document.getElementById('wzry');
    phone.replaceChild(chui,wzry);//替换
</script>
</body>
</html>

复制节点

node.cloneNode(boolean)将 HTML 页面中指定元素节点(标签)进行复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>复制节点</title>
</head>
<body>
<button id="btn">按钮</button>
<br>
<p id="p1" style="color: lightcoral;">这是一个段落.</p>
<script>
     /*
       node.cloneNode(Boolean)
       cloneNode() 方法创建节点的拷贝,并返回该副本。
       cloneNode() 方法克隆所有属性以及它们的值。
     */

     var btn = document.getElementById('btn');
     var btn1 = btn.cloneNode(true);
     console.log(btn1);

     var p1 = document.getElementById('p1');
     p1.appendChild(btn1);
</script>
</body>
</html>

需要说明的是: cloneNode() 方法的参数表示是否采用深度克隆。如果为true,则该节点的所有后代节点也都会被克隆;如果为false,则只克隆该节点本身。
我们可以通过如下示例来学习插入节点的使用:

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注