【第五部分 | JS WebAPI】3:DOM 节点操作

目录

| 节点操作

1-1 概述

2-1 获取父节点

3-1 获取子节点(获取所有子对象 不推荐)

3-2 获取子节点(获取所有子【元素节点】)

3-3 获取首尾子节点

4-1 获取兄弟节点

5-1 动态创建、添加节点

5-2 案例:评论区

5-4 删除节点

5-5 复制节点

| 综合案例:动态生成表格

| 三种动态创建元素的区别

| 总结


| 节点操作


1-1 概述

什么是节点?

  • 网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。我们常用的是元素节点

  • HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以 创建或删除。

  • 一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个 基本属性。

  • 我们在实际开发中,节点操作主要操作的是元素节点

什么是节点操作?

代码示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <span></span>
    </div>

    <script>
        // 如果以前想得到div和span元素,需要进行两步
        var divObj = document.getElementsByTagName('div');
        var spanObj = document.getElementsByTagName('span');

        // 而我们若使用节点操作来获取父元素,则只需要获取某一个元素对象,然后根据这个元素对象和其它元素对象的层级关系,使用对应的函数即可
        // span是div的父节点。我们得到了span,则只需要操作这个节点,使用parentNode就可以获取其父节点对象div了
        var spanObj2 = document.getElementsByTagName('span');
        divObj2 = spanObj2[0].parentNode;
        console.log(divObj2);  //div
    </script>
</body>
</html>

2-1 获取父节点


3-1 获取子节点(获取所有子对象 不推荐)

 

子元素的标签、换行符会被认为是节点。 如下列代码,若使用

var ul = document.getElementsByTags('ul');

var lis = ul.childNodes;

代码,则会获得的不仅仅是一个含有2个li的元素对象伪数组,而是一个含有5个元素对象的伪数组

具体原因如下

<ul>(换行 第一个节点)
	<li(标签,第二个节点)>XXX</li>(换行,第三个节点)
	<li(标签,第四个节点)>XXX</li>(换行,第五个节点)
</ul>

  • 综上,因为返回值里面包含了所有的子节点,包括元素节点,文本节点等。 如果只想要获得里面的元素节点,则需要专门处理。 所以我们一般不提倡使用childNodes


3-2 获取子节点(获取所有子【元素节点】)

parentNode.children

代码示例(childNode 和 children 的对比)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>

    <script>
        var divObj = document.querySelector('div');
        var children1 = divObj.childNodes;
        var children2 = divObj.children;

        var str1 = '';
        var str2 = '';

        for(var i=0 ; i<children1.length ; i++) {
            str1 += children1[i];
        }
        for(var i=0 ; i<children2.length ; i++) {
            str2 += children2[i];
        }

        console.log(str1); //[object Text][object HTMLSpanElement][object Text][object HTMLSpanElement][object Text][object HTMLSpanElement][object Text][object HTMLSpanElement][object Text]
        console.log(str2); //[object HTMLSpanElement][object HTMLSpanElement][object HTMLSpanElement][object HTMLSpanElement]

    </script>
</body>
</html>
 

3-3 获取首尾子节点

注意:firstChild得到的  该子节点包含“换行符等非元素节点”

下列两个方法可以获取的是首尾子【元素】节点

 


实际开发中,如何用兼容IE9以下版本浏览器的方法得到 firstElementChild 和 lastElementChild ?

实际开发中,firstChild 和 lastChild 包含其他节点,操作不方便,而 firstElementChild 和 lastElementChild 又有兼容性问题,那么我们如何获取第一个子元素节点或最后一个子元素节点呢?

解决方案:

1.如果想要第一个子元素节点,可以使用 parentNode.chilren[0]

2.如果想要最后一个子元素节点,可以使用 parentNode.chilren[parentNode.chilren.length - 1]


4-1 获取兄弟节点

注意:该方法得到的 兄弟节点包含“换行符等非元素节点”

 node.nextSibling  //返回当前元素的下一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。
 node.previousSibling  // 返回当前元素上一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。

下列两个方法可以获取的是兄弟子【元素】节点

 node.nextElementSibling   //返回当前元素下一个兄弟元素节点,找不到则返回null。
 node.previousElementSibling   //g 返回当前元素上一个兄弟节点,找不到则返回null。

可以自己封装一个兼容IE9以下浏览器的获取兄弟子【元素】节点的函数

 function getNextElementSibling(element) {
 	var el = element;
 	while (el = el.nextSibling) {
	 	if (el.nodeType === 1) {
	 		return el;
 		}
 	}
 	return null;
 } 

5-1 动态创建、添加节点

  • 使用场景:如想给 ul 中动态地添加 li


代码示例

基本步骤:获取父节点元素 → 创建要插入的元素 → 插入元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul>

    </ul>
    <script>
        // 动态创建元素节点
        var liElement = document.createElement('li');
        // 把创建的元素节点加入(获取父节点 → 添加子节点)
        var ulNode = document.querySelector('ul');
        ulNode.appendChild(liElement);
    </script>
</body>
</html>

5-2 案例:评论区

核心思路︰点击按钮之后,就动态创建一个li,添加到ul里面。创建li的同时,把文本域里面的值通过li.innerHTML赋值给li

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        li {
            list-style: none;
        }

        textarea{
            display: block;

            resize:none;  /* 取消拖拽 */
            outline: none;/* 取消选中高亮 */
            height: 200px;
            width: 500px;
            margin: 100px auto;
            margin-bottom: 30px;
            background-color: aliceblue;
            padding: 10px;

            font-family: 'Microsoft YaHei';
            font-size: 20px;
        }

        button {
            display: block;

            background-color: lightskyblue;
            width: 100px;
            height: 40px;
            margin: 0 auto;
        }

        ul {
            width: 500px;
            margin: 40px auto;
            background-color: lightgoldenrodyellow;
        }

        li {
            width: 500px;
            margin: 5px auto;
            height: 30px;
            border-bottom: 1px solid grey;
        }

    </style>
</head>
<body>
    <textarea placeholder="输入评论" name="comment"></textarea>
    <button>发布</button>
    <ul>
    </ul>

    <!-- 点击按钮,获取文本域,然后添加li -->
    <script>
        var btn = document.querySelector('button');
        var text = document.querySelector('textarea');

        btn.onclick = function(){
            // 获取文本域文本
            var textContent = text.value;
            //创建li节点
            var newLi = document.createElement('li');
            //添加li节点
            var ul = document.querySelector('ul');
            ul.appendChild(newLi);
            // 向li节点中添加内容 innerHTML
            newLi.innerHTML = textContent;
            // 清空文本
            text.value = '';
        }
    </script>
</body>
</html>

5-4 删除节点

代码示例


5-5 复制节点

代码示例

 


| 综合案例:动态生成表格

目前还没学习Ajax,无法动态通过数据库获取数据。因此我们把数据写在对象中

注意体会上述知识的综合使用:

  • CSS 和 Html的知识

  • 数组存放对象

  • 循环创建事件

  • 如何在table的tbody中插入行、在行中插入列

  • 注意删除按钮的书写 要使用innerHTML方法以渲染html标签

  • 注意删除的时候,删除的是 相对于a 的父亲(tr)的父亲(td),即删除行的那个元素节点。

示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        table {
            width: 500px;
            margin: 100px auto;
            border-collapse: collapse;
            text-align: center;
        }
        
        td,
        th {
            border: 1px solid #333;
        }
        
        thead tr {
            height: 40px;
            background-color: #ccc;
        }
    </style>
</head>

<body>
    <table cellspacing="0">
        <thead>
            <tr>
                <th>姓名</th>
                <th>科目</th>
                <th>成绩</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>

        </tbody>
    </table>
    <script>
        // 1.先去准备好学生的数据
        var datas = [{
            name: '魏璎珞',
            subject: 'JavaScript',
            score: 100
        }, {
            name: '弘历',
            subject: 'JavaScript',
            score: 98
        }, {
            name: '傅恒',
            subject: 'JavaScript',
            score: 99
        }, {
            name: '明玉',
            subject: 'JavaScript',
            score: 88
        }, {
            name: '大猪蹄子',
            subject: 'JavaScript',
            score: 0
        }];
        // 2. 往tbody 里面创建行: 有几个人(通过数组的长度)我们就创建几行
        var tbody = document.querySelector('tbody');
        for (var i = 0; i < datas.length; i++) { // 外面的for循环管行 tr
            // 1. 创建 tr行
            var tr = document.createElement('tr');
            tbody.appendChild(tr);
            // 2. 行里面创建单元格(跟数据有关系的3个单元格) td 单元格的数量取决于每个对象里面的属性个数  for循环遍历对象 datas[i]
            for (var k in datas[i]) { // 里面的for循环管列 td
                // 创建单元格 
                var td = document.createElement('td');
                // 把对象里面的属性值 datas[i][k] 给 td  
                // console.log(datas[i][k]);
                td.innerHTML = datas[i][k];
                tr.appendChild(td);
            }
            // 3. 创建有删除2个字的单元格 
            var td = document.createElement('td');
            td.innerHTML = '<a href="javascript:;">删除 </a>';
            tr.appendChild(td);

        }
        // 4. 删除操作 开始 
        var as = document.querySelectorAll('a');
        for (var i = 0; i < as.length; i++) {
            as[i].onclick = function() {
                // 点击a 删除 当前a 所在的行(链接的爸爸的爸爸)  a的爸爸是tr,tr的爸爸是td,因此删除的是td。注意使用的是this 
                tbody.removeChild(this.parentNode.parentNode)
            }
        }
        // for(var k in obj) {
        //     k 得到的是属性名
        //     obj[k] 得到是属性值
        // }
    </script>
</body>

</html>

| 三种动态创建元素的区别

| 总结

 

 

 

猜你喜欢

转载自blog.csdn.net/m0_57265007/article/details/127981342