DOM(三):节点操作——获取父子兄节点、节点的增删;案例动态生成表格

本文介绍了HTMLDOM中节点的概念,包括节点类型、节点关系(如父子、同胞),以及如何通过JavaScript操作节点,如添加、删除和克隆元素。还展示了动态生成表格的示例,对比了innerHTML和createElement在创建元素效率上的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ps:这一部分是看教程和其他博主的学习笔记写的没有看视频。 

一、节点概述

在 HTML DOM 中,所有事物都是节点。DOM 是被视为节点树的 HTML。

网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM中,节点使用node来表示。HTML DOM树中的所有节点均可通过JavaScript进行访问,所有HTML元素(节点)均可被修改,也可以创建或删除。

根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:

  • 整个文档是一个文档节点
  • 每个 HTML 元素是元素节点
  • HTML 元素内的文本是文本节点
  • 每个 HTML 属性是属性节点
  • 注释是注释节点

二、节点父、子和同胞(兄弟和姐妹)

(1)节点树中的节点彼此拥有层级关系。

我们常用父(parent)子(child)同胞(sibling)等术语来描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)

  • 在节点树中,顶端节点被称为根(root)。
  • 每个节点都有父节点、除了根(它没有父节点)。
  • 一个节点可拥有任意数量的子节点。
  • 同胞是拥有相同父节点的节点

 

(2) 父节点操作

语法:子节点.parentNode,得到的是一个元素不是集合

获取父节点:

   <div class="yg"></div>
    <script>
        var yg = document.querySelector('.yg');
        // 获取父节点
        console.log(yg.parentNode);
    </script>

(3)子节点操作

 1.父节点.childNodes(用的不多比较麻烦)

这个得到的是所有的子节点,除了我们想要的元素节点,还有换行、空格等文本节点,所以要想拿到元素,就要循环遍历,因为元素节点nodeType是1,属性2,文本3。这个挺麻烦的

2.父节点.children(常用的) 

这个只返回子元素节点.

(4)获取第一个子元素和最后一个子元素

父节点.firstChild和父节点.lastChild返回的是所有类型节点中的第一个和最后一个,这两个用的不多,下面这两个用的多一点:
父节点.firstElementChild和父节点.lastElementChild,这俩都是返回的第一个和最后一个元素节点,但是!这个不错的方法,只有IE9以上支持

其实在实际开发中,我们都会用父元素.children[i],既没有兼容问题,又能返回首尾元素节点

比如:

var ul = document.querySelector('ul');
console.log(ul.children[0]);
console.log(ul.children[ul.children.length - 1]);

案例:下拉菜单

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

li {
    list-style: none;
}

a {
    color: black;
    text-decoration: none;
}

.box {
    margin: 100px auto;
    width: 400px;
    height: 50px;
}

.box>li {
    float: left;
    /* position: relative; */
    width: 100px;
    height: 50px;
    line-height: 50px;
    text-align: center;
}

.box>li a {
    display: inline-block;
    width: 100px;
    height: 50px;
}

.box>li a:hover {
    background-color: #ccc;
}

.box ul {
    display: none;
    /* position: absolute; */
    left: 0;
    top: 50px;
    border-left: 1px solid red;
    border-right: 1px solid red;
}

.box ul li {
    border-bottom: 1px solid red;
}

.box li ul li:hover {
    background-color: rgb(247, 149, 149);
}
   <ul class="box">
        <li>
            <a href="#">微博</a>
            <ul>
                <li>私信</li>
                <li>评论</li>
                <li>@我</li>
            </ul>
        </li>
        <li>
            <a href="#">微博</a>
            <ul>
                <li>私信</li>
                <li>评论</li>
                <li>@我</li>
            </ul>
        </li>
        <li>
            <a href="#">微博</a>
            <ul>
                <li>私信</li>
                <li>评论</li>
                <li>@我</li>
            </ul>
        </li>
        <li>
            <a href="#">微博</a>
            <ul>
                <li>私信</li>
                <li>评论</li>
                <li>@我</li>
            </ul>
        </li>
    </ul>

接下来是js部分,其实还是好理解的: 

   var box = document.querySelector('.box'); //这个地方
    var lis = box.children;  //得到4个li
    for (var i = 0; i < lis.length; i++) {
        lis[i].onmouseover = function () {
        //鼠标放上去,这个li的第二个孩子(ul)显示
            this.children[1].style.display = 'block';
        }
        lis[i].onmouseout = function () {
            this.children[1].style.display = 'none';
        }
    }

 

 (5)获取兄弟节点

实际上兄弟节点用的少,了解下就行了。

和父子一样,有个获取下一个(全部中的下一个)节点和上一个节点的方法,没什么用

 真正有用的是下面这个,但是又有兼容性问题

 如何解决兼容性问题:

三、节点的增删 

1.创建和添加元素节点

先创建,再添加
比如我要创建一个li的元素节点:creatElement('li')

var myli = document.createElement('li');

(1)添加:父元素.appendChild(要添加的元素)

先获取它的父元素,然后把我创建的li添加进去,默认是添加到父元素的尾部

var ul = document.querySelector('ul');
//把我创建的li放到ul里面去,默认添加到尾部
ul.appendChild(myli);

(2)父元素.insertBefore(要添加的元素节点,添加到谁前面)

下面这个代码就是在ul的第一个孩子前添加我创建的li

ul.insertBefore(myli, ul.children[0]);

(3)简单添加留言案例

<textarea name="" id="content" cols="30" rows="10"></textarea> <button>发布</button>
<ul class="my">
    <li></li>
</ul>

注意获取textarea和input里面的值是.value

//简单留言案例
	var content = document.querySelector('textarea');//获取文本域
	var my = document.querySelector('.my');  //获取ul
	var btn = document.querySelector('button');  //获取button
	//点击按钮就生成一个li,添加到ul里
	btn.onclick = function () {
	    if (content.value == '') {
	        alert('您没有输入任何内容');
	    } else {
	        var li = document.createElement('li');
	        li.innerHTML = content.value;
	        // my.appendChild(li);
	        my.insertBefore(li, my.children[0]);
	    }
	}

2.删除元素节点

(1)使用父元素.removeChild(子元素)

<button>删除</button>
<ul>
    <li>zzy</li>
    <li>aoaoao</li>
    <li>3213</li>
</ul>
	var ul = document.querySelector('ul');
	var btn = document.querySelector('button');
	btn.onclick = function () {
	    if (ul.children.length != 0) {
	        ul.removeChild(ul.children[0]);
	    } else {
	        //如果删完了就禁用按钮
	        this.disabled = true;
	    }
	
	}

(2)添加留言和删除留言(上面案例的升级版) 

这里遇到个问题就是删除留言的代码要放到btn.onclick里面,要不然会先执行下面这段(注意代码的执行顺序),等点击btn的时候才添加a标签,那样先获取的as就是空了

//简单添加删除留言案例
var content = document.querySelector('textarea');//获取文本域
var my = document.querySelector('.my');  //获取ul
var btn = document.querySelector('button');  //获取button
//1.添加留言:点击按钮就生成一个li,添加到ul里
btn.onclick = function () {
    if (content.value == '') {
        alert('您没有输入任何内容');
    } else {
        var li = document.createElement('li');
        //把textarea里面的内容取过来,然后再添加一个a标签
        li.innerHTML = content.value + "<a href='javascript:;'>删除</a>";//卧槽,还能这么写
        // my.appendChild(li);
        my.insertBefore(li, my.children[0]);
    }

    //2.删除留言
    //先获取a标签
    //这段代码要放到btn.onclick里面,要不然会先执行下面这段,等点击btn的时候才添加a标签,那样as就是空了
    var as = document.querySelectorAll('a');
    for (var i = 0; i < as.length; i++) {
        as[i].onclick = function () {
            my.removeChild(this.parentNode);
        }
    }
}

 3.复制元素节点

(1)语法:node.cloneNode()

把ul里的第一个孩子复制过来,放到ul的尾部

	var ul = document.querySelector('ul');
	var li1 = ul.children[0].cloneNode();
	ul.appendChild(li1);

(2)浅拷贝和深拷贝

node.cloneNode()括号里默认是false,也就是浅拷贝,只copy元素不copy内容
node.cloneNode(true),如果括号里是true就是深拷贝,copy元素和内容

四、动态生成表格 

1.创建html csss

table {
    width: 400px;
    margin: 100px auto;
    text-align: center;
    border-collapse: collapse;
}

th,
td {
    border: 1px solid #333;
}

thead tr {
    height: 40px;
    background-color: #ccc;
}

tbody tr {
    height: 30px;
}
<table cellspacing="0">
    <thead>
        <tr>
            <th>姓名</th>
            <th>科目</th>
            <th>成绩</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>

    </tbody>

 2.先准备好学生的数据,以对象形式存储在数组中

var datas = [
    {
        names: '彭于晏',
        subject: 'javascript',
        score: 87
    },
    {
        names: '小婷',
        subject: 'javascript',
        score: 100
    }, {
        names: '张大仙',
        subject: 'javascript',
        score: 99
    }, {
        names: '刘亦菲',
        subject: 'javascript',
        score: 60
    }
]

3.创建行tr

var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {
    //先创建,再添加,二者要绑定在一起
    var tr = document.createElement('tr');
    tbody.appendChild(tr);
}

4.创建行里面的单元格td

var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {
    //先创建,再添加,二者要绑定在一起
    var tr = document.createElement('tr');
    tbody.appendChild(tr);
    //3.行里面创建单元格td
    for (var k in datas[i]) {  //遍历对象,k是属性的个数,有几个属性就循环几次
        var td = document.createElement('td');
        tr.appendChild(td);
}

5.添加td里面的数据

var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {
    //先创建,再添加,二者要绑定在一起
    var tr = document.createElement('tr');
    tbody.appendChild(tr);
    //3.行里面创建单元格td
    for (var k in datas[i]) {  //遍历对象,k是属性的个数,有几个属性就循环几次
        var td = document.createElement('td');
        //给每个单元格塞数据
        td.innerHTML = datas[i][k];
        tr.appendChild(td);
    }
}

 

6.添加删除操作的链接 

var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {
    //先创建,再添加,二者要绑定在一起
    var tr = document.createElement('tr');
    tbody.appendChild(tr);
    //3.行里面创建单元格td
    for (var k in datas[i]) {  //遍历对象,k是属性的个数,有几个属性就循环几次
        var td = document.createElement('td');
        //4.给每个单元格先塞数据,再放到tr里
        td.innerHTML = datas[i][k];
        tr.appendChild(td);
    }
    //5.添加删除操作的链接
    var tdend = document.createElement('td');
    tdend.innerHTML = "<a href='javascript:;'>删除</a>";
    tr.appendChild(tdend);
}

 7.最后一步,给删除操作添加删除事件

//2.先创建行tr,有几个人就创建几行
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {
    //先创建,再添加,二者要绑定在一起
    var tr = document.createElement('tr');
    tbody.appendChild(tr);
    //3.行里面创建单元格td
    for (var k in datas[i]) {  //遍历对象,k是属性的个数,有几个属性就循环几次
        var td = document.createElement('td');
        //4.给每个单元格先塞数据,再放到tr里
        td.innerHTML = datas[i][k];
        tr.appendChild(td);
    }
    //5.添加删除操作的链接
    var tdend = document.createElement('td');
    tdend.innerHTML = "<a href='javascript:;'>删除</a>";
    tr.appendChild(tdend);
}

//6.给删除按钮添加事件
var as = document.querySelectorAll('a'); //这里一定要是All
for (var i = 0; i < as.length; i++) {
    as[i].onclick = function () {
        tbody.removeChild(this.parentNode.parentNode);
    }
}

 五、innerHTML和createElement创建元素谁效率更高?

在这里插入图片描述
如果innerHTML是拼接字符串标签的话,拼1000个要用3000ms,但是如果采用数组形式拼接,只用7ms
如果用createElement创建1000个同样的元素,大概18ms 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值