温故知新——DOM节点增删查改替换复制

本文详细介绍了DOM中针对element节点的创建、修改、插入、删除、替换和复制等操作,包括createElement、innerText、textContent、appendChild、insertBefore、removeChild、replaceChild和cloneNode等方法。此外,还探讨了innerHTML属性的使用及其潜在的安全问题。

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

DOM节点增删查改替换复制

这篇文章中总结的节点操作比较狭义,特指对 element 节点的操作,并没有包含其他内容,至于对文本内容和属性的操作就放在下一篇吧~

节点的“查”操作已经在上一篇文章中总结过了,在本文中主要包括创建节点、修改节点、插入节点、删除节点、替换节点、查看节点和复制节点

今天的通过下面这一段范例代码展开:

<ul id="users">
  <li class="user">小A君</li>
  <li class="user">小C君</li>
</ul>

我们可以设想这样一个应用场景,根据上面的结构,创建两个新的“小B君”和“小D君”,按照 ABCD 的顺序插入到上面的列表中

那么我们就开始吧~

创建节点

createElement

创建 element 节点主要依赖 createElement 方法,这个方法接受一个参数,即要创建的标签名:

let tempLi = document.createElement('li');
console.log(tempLi); // <li></li>

这个标签名并不区分大小写,但是按照标准最好还是采用小写~

当 element 被创建的时候,它所属的 document 就被设置好了,

修改节点

当一个空的 element 创建出来后,就要根据我们的需求为其添加内容

如果我们要添加的是文本内容,可以采用下面的几个方法;

  • innerText
  • textContent

而关于添加(插入)节点的内容就放在下一节 插入节点

innerText

innerText 属性是一个可读可写的属性,它可以操作元素中包含的所有文本内容,包括子文档树中的文本。在通过innerText读取值时,它会按照由浅入深地顺序,将子文档树中的所有文本拼接起来。在通过innerText写入值时,结果会删除元素的所有子节点,插入包含相应文本值的文本节点

console.log(document.getElementById('users').innerText); // 小A君 小B君 

而当我们进行写操作的时候,会直接将这个 element 中的所有子节点清除并添加一个文本节点(可以采用 element.innerText = '' 来清空一个元素),猜一下当我们执行下面这段代码的时候会发生什么:

let usersEle = document.getElementById('users');
usersEle.innerText = usersEle.innerText;

(如果真的写了这样的代码会被人打死的吧,咳咳~)

textContent

这个属性和 innerText 的使用方法基本一致,textContent 属性与 innerText 属性类似,该属性可读写。在读模式下,返回当前节点和它的所有后代节点的文本内容;在写模式下,结果会删除元素的所有子节点,插入包含相应文本值的文本节点

他们的主要区别在于 innerText 是 element 的属性,而 textContent 是 node 的属性且 textContent 不兼容 IE9 以下浏览器

console.log(document.getElementById('users').textContent); // 小A君 小B君 

插入节点

在创建好节点并添加好内容之后我们应该将节点插入到他们的父节点中了,插入节点的方法也不止一种

  • appendChild
  • insertBefore

appendChild

这个方法的作用可以很明显通过方法名理解,就是直接将一个 child 节点 append 进来,在节点的最后追加一个子节点

使用方法:

let tempLi = document.createElement('li');
tempLi.innerText = "小D君";
document.getElementById('users').appendChild(tempLi);

由于这个方法只能将节点添加到父节点的最后,所以在使用时需要注意顺序方面的要求,通常的做法是先进行一定的排序后再调用这个方法

⚠️注意: 如果要添加的节点已经存在在这个 document 中了,并不是新创建出来的 element,这时会发生的并不是单纯的插入,而是“移动”

<!-- html body -->
<ul id="users">
  <li class="user">小A君</li>
  <li class="user">小C君</li>
</ul>
<script>
  document.getElementById('users').appendChild(
    document.getElementsByClassName('user')[0]
  )
</script>

insertBefore

insertBefore() 方法接收两个参数:要插入的节点和作为参照的节点。插入节点后,被插入的节点会变成参照节点的前一个兄弟节点(previousSibling),同时被方法返回。如果参照节点是null,则insertBefore()与appendChild()方法执行相同的操作

同样地,如果插入的节点已经是文档的一部分了,那结果就是将该节点从原来的位置转移到新位置

这个方法就更加适合 “小B君” 的插入

let tempLi = document.createElement('li');
tempLi.innerText = "小B君";
document.getElementById('users').insertBefore(
  tempLi,
  document.getElementsByClassName('user')[1]
);

删除节点

removeChild

removeChild 方法接收一个参数,即要移除的节点,被移除的节点成为方法的返回值

let user0 = document.getElementsByClassName('user')[0];
document.getElementById('users').removeChild(user0);

remove()

remove 方法不太常见,直接在当前节点使用 remove() 方法就可以删除该节点,无返回值

要实现和上面一样的效果只需要

document.getElementsByClassName('user')[0].remove();

替换节点

replaceChild

replaceChild 接收的两个参数是要插入的节点和要替换的节点,要替换的节点将由这个方法返回并从文档树中移除,同时由要插入的节点占据其位置

let tempLi = document.createElement('li');
tempLi.innerText = "替换节点";
document.getElementById('users').replaceChild(
  tempLi,
  document.getElementsByClassName('user')[0]
);

复制节点

cloneNode

cloneNode 方法用于克隆一个节点

调用者是要被复制的 node,返回值是这个 node 的副本

它接受一个布尔值作为参数,表示是否执行深复制。在参数为true时,执行深复制,也就是复制节点及整个子节点树。在参数为false的情况下,执行浅复制,即复制节点本身

let dupUsers = document.getElementById('users').cloneNode(true);
console.log(dupUsers);

⚠️注意: 由于不同版本规范中 cloneNode 方法的默认参数不同,所以请一定加上参数

终极大招 innerHTML

上述提到的所有问题,都可以通过 innerHTML 解决

这个方法和前文中提到的 innerText 很相似

  • 在读模式下,返回与调用元素的所有子节点(包括元素、注释和文本节点)对应的HTML字符串;
  • 在写模式下,innerHTML会根据指定的值创建新的DOM树,然后用这个DOM树完全替换调用元素原先的所有子节点

我们可以在读模式下获取到我们要操作的 node 或者他的 父节点,之后通过字符串处理方法进行操作,然后再写入

但是我们一般不会这样做

主要是因为它存在安全问题,innerHTML不会检查代码,直接运行,会有风险

所以innerHTML方法建议仅用于新的节点,比如创建插入,内容最好是可控的,而不是用户填写的内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值