前端基础——JavaScript(WebAPI)(下篇)

目录

操作节点

新增节点

1.创建元素节点

2.插入节点到dom树中

1) 使用 appendChild 将节点插入到指定节点的最后一个孩子之后 使用 appendChild 将节点插入到指定节点的最后一个孩子之后)

2) 使用 insertBefore 将节点插入到指定节点之前 使用 insertBefore 将节点插入到指定节点之前)

注意事项

[注意1: 如果针对一个节点插入两次, 则只有最后一次生效(相当于把元素移动了)](#注意1: 如果针对一个节点插入两次, 则只有最后一次生效(相当于把元素移动了))

[注意2: 一旦一个节点插入完毕, 再针对刚刚的节点对象进行修改, 能够同步影响到 DOM 树中的内容](#注意2: 一旦一个节点插入完毕, 再针对刚刚的节点对象进行修改, 能够同步影响到 DOM 树中的内容)

删除节点

返回值为该被删除节点

[被删除节点只是从 dom 树被删除了, 但是仍然在内存中, 可以随时加入到 dom 树的其他位置.](#被删除节点只是从 dom 树被删除了, 但是仍然在内存中, 可以随时加入到 dom 树的其他位置.)

[如果上例中的 child节点 不是 element 节点的子节点,则该方法会抛出异常](#如果上例中的 child节点 不是 element 节点的子节点,则该方法会抛出异常)


书接前文:前端基础------JavaScript(WebAPI)(上篇)~~

操作节点

新增节点

分成两个步骤

  1. 创建元素节点

  2. 把元素节点插入到 dom 树中.

第一步相当于生了个娃, 第二步相当于给娃上户口

1.创建元素节点

使用 createElement 方法来创建一个元素. options 参数暂不关注

javascript 复制代码
var element = document.createElement(tagName[, options]);

代码示例:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

</body>
<script>
    //创建一个 h3 的节点
    let element = document.createElement('h3')
    element.innerHTML = "这是我们创建的一个新的节点"
</script>
</html>

此时发现👇, 虽然创建出新的 div 了, 但是 div 并没有显示在页面上. 这是因为新创建的节点并没有加入到DOM 树中

2.插入节点到dom树中

1) 使用 appendChild 将节点插入到指定节点的最后一个孩子之后
javascript 复制代码
element.appendChild(aChild)
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        
    </div>
</body>
<script>
    //创建一个 h3 的节点
    let element = document.createElement('h3')
    element.innerHTML = "这是我们创建的一个新的节点"
    let div = document.querySelector('div')
    div.appendChild(element)
</script>
</html>

效果展示👇

那么 "将节点插入到指定节点的最后一个孩子之后" 是什么意思呢??👇

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <p>这是一个p标签1</p>
        <p>这是一个p标签2</p>
        <p>这是一个p标签3</p>
    </div>
</body>
<script>
    //创建一个 h3 的节点
    let element = document.createElement('h3')
    element.innerHTML = "这是我们创建的一个新的节点"
    let div = document.querySelector('div')
    div.appendChild(element)
</script>
</html>

可以看到,插入的节点确实插在了指定标签最后一个孩子"这是一个p标签3"的后面👇

2) 使用 insertBefore 将节点插入到指定节点之前
javascript 复制代码
var insertedNode = parentNode.insertBefore(newNode, referenceNode);

insertedNode 被插入节点(newNode)

parentNode 新插入节点的父节点

newNode 用于插入的节点

referenceNode newNode 将要插在这个节点之前

如果 referenceNode 为 null 则 newNode 将被插入到子节点的末尾.

注意: referenceNode 引用节点不是可选参数

代码展示👇

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <!-- 我们这次要插到这个地方 -->
        <p class="p1">这是一个p标签1</p>
        <p>这是一个p标签2</p>
        <p>这是一个p标签3</p>
    </div>
</body>
<script>
    //创建一个 h3 的节点
    let element = document.createElement('h3')
    element.innerHTML = "这是我们创建的一个新的节点"
    let div = document.querySelector('div')
    div.appendChild(element)

    let new_node = document.createElement('p')
    new_node.innerHTML = "这是一个新p标签"
    //插入的时候选中我们要插入哪个标签前面
    div.insertBefore(new_node,document.querySelector('.p1'))
</script>
</html>

此时我们发现,就把新创建的 p 标签插在第一个节点之前了,效果展示👇

如果把插入的位置改成 null 呢??是不是就代表着我们不知道插入到哪里👇

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <!-- 我们这次要插到这个地方 -->
        <p class="p1">这是一个p标签1</p>
        <p>这是一个p标签2</p>
        <p>这是一个p标签3</p>
    </div>
</body>
<script>
    //创建一个 h3 的节点
    let element = document.createElement('h3')
    element.innerHTML = "这是我们创建的一个新的节点"
    let div = document.querySelector('div')
    div.appendChild(element)

    let new_node = document.createElement('p')
    new_node.innerHTML = "这是一个新p标签"
    //插入的时候选中我们要插入哪个标签前面
    //这里将 document.querySelector('.p1') 改为 null
    div.insertBefore(new_node,null)
</script>
</html>

效果展示👇

此时我们发现,它就会插入到我们指定标签的最后一个节点后面~~

注意事项
注意 **1:**如果针对一个节点插入两次, 则只有最后一次生效(相当于把元素移动了)
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <p class="p1">这是一个p标签1</p>
        <p class="p2">这是一个p标签2</p>
        <p class="p3">这是一个p标签3</p>
    </div>
</body>
<script>
    //创建一个 h3 的节点
    let element = document.createElement('h3')
    element.innerHTML = "这是我们创建的一个新的节点"
    let div = document.querySelector('div')
    div.appendChild(element)

    let new_node = document.createElement('p')
    new_node.innerHTML = "这是一个新p标签"
    //插入的时候选中我们要插入哪个标签前面
    //第一次把new_node插入到p1前面
    div.insertBefore(new_node,document.querySelector('.p1'))
    //第二次把new_node插入到p2前面
    div.insertBefore(new_node,document.querySelector('.p2'))
    //第三次把new_node插入到p3前面
    div.insertBefore(new_node,document.querySelector('.p3'))
</script>
</html>

效果展示👇

我们发现多次拿着 new_node 往里插入的时候,只有最后一次生效了,最终还是插入到了 p3 前面~~

注意 **2:**一旦一个节点插入完毕, 再针对刚刚的节点对象进行修改, 能够同步影响到 DOM 树中的内容
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <p class="p1">这是一个p标签1</p>
        <p class="p2">这是一个p标签2</p>
        <p class="p3">这是一个p标签3</p>
    </div>
</body>
<script>
    //创建一个 h3 的节点
    let element = document.createElement('h3')
    element.innerHTML = "这是我们创建的一个新的节点"
    let div = document.querySelector('div')
    div.appendChild(element)

    let new_node = document.createElement('p')
    new_node.innerHTML = "这是一个新p标签"
    //插入的时候选中我们要插入哪个标签前面
    //第一次把new_node插入到p1前面
    div.insertBefore(new_node,document.querySelector('.p1'))
    //第二次把new_node插入到p2前面
    div.insertBefore(new_node,document.querySelector('.p2'))
    //第三次把new_node插入到p3前面
    div.insertBefore(new_node,document.querySelector('.p3'))

    //插入后再修改刚刚的节点对象,也能够同步影响 DOM 树的内容
    element.innerHTML = "我正在修改p标签的内容"
</script>
</html>

效果展示👇我们发现确实修改了~~

删除节点

使用 removeChild 删除子节点

javascript 复制代码
oldChild = element.removeChild(child);

child 为待删除节点

element 为 child 的父节点

返回值为该被删除节点

被删除节点只是从 dom 树被删除了, 但是仍然在内存中, 可以随时加入到 dom 树的其他位置.

如果上例中的 child节点 不是 element 节点的子节点,则该方法会抛出异常

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 删除最后一个节点 -->
    <div class="container">
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
    </div>
</body>
</html>

此时的页面效果👇

我们下面来删除最后一个节点 4👇

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 删除最后一个节点 -->
    <div class="container">
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div id="delete">4</div>
    </div>
</body>
</html>
<script>
    let parent = document.querySelector(".container")
    let child = document.querySelector("#delete")
    parent.removeChild(child)
</script>

效果展示👇

返回值为该被删除节点

那么此时我能不能把我删除了的元素再给它插入进去呢??也是可以的

我们先来看一下 element 的返回值👇

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 删除最后一个节点 -->
    <div class="container">
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div id="delete">4</div>
    </div>
</body>
</html>
<script>
    let parent = document.querySelector(".container")
    let child = document.querySelector("#delete")
    let element = parent.removeChild(child)
    console.dir(element)
</script>

我们发现它的返回值是 4,效果展示👇

被删除节点只是从 dom 树被删除了, 但是仍然在内存中, 可以随时加入到 dom 树的其他位置.

我们只需用 appendChild(child) 就可以把 4 给插入回去👇

javascript 复制代码
<script>
    let parent = document.querySelector(".container")
    let child = document.querySelector("#delete")
    let element = parent.removeChild(child)
    console.dir(element)
    parent.appendChild(child)
</script>

效果展示👇

如果上例中的 child节点 不是 element 节点的子节点,则该方法会抛出异常

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 此时 id="delete"这个元素和 container 之间就不存在父子关系了 -->
    <div class="container">
    </div>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div id="delete">4</div>
</body>
</html>
<script>
    let parent = document.querySelector(".container")
    let child = document.querySelector("#delete")
    let element = parent.removeChild(child)
</script>

效果展示👇

此时就报错了:删除失败,这个节点不是我们要删除节点的一个子节点

所以说我们对应的 remove API 这里它的入参 child 和我们对应前面的这个对象,它们之间没有父子关系的话,就会出现报错~~
更多关于 Web API 的内容大家可以参考手册:JavaScript HTML DOM

相关推荐
魔都吴所谓2 小时前
【Python】 多线程 & 多进程&协程 常见题 + 应用场景整理
开发语言·python
萧瑟余晖2 小时前
Spring Cloud Gateway详解
spring cloud·面试
Irene19912 小时前
Flink 学习日志 01:前端转大数据的实战避坑指南
java·jvm·flink
Thomas.Sir2 小时前
第1课:SpringBoot 4.x 快速上手:新特性、环境准备与第一个HelloWorld程序
java·spring boot
king13598745502 小时前
LiteRT Tensor API:C++ 编写端侧模型图,XNNPACK、GPU 与 NPU 怎么选?
开发语言·c++·人工智能·chatgpt·架构·aigc
geovindu2 小时前
rust: Template Method Pattern(续)
开发语言·后端·设计模式·rust·行为模式·板方法模式
外收内放2 小时前
面向对象高级(封装)
开发语言·python
tryCbest2 小时前
Vue3——第 6 篇:事件处理与表单绑定——v-on 与 v-model
前端·javascript·vue.js
恋猫de小郭2 小时前
Flutter 的文字为什么比 SwiftUI 更细?问题主要在 Skia 的 256 项查找表里
android·前端·flutter
lexiangqicheng2 小时前
前端高阶面试核心通关指南:深入解析Vue3与React18底层原理及性能优化
前端·面试·性能优化