前端基础——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

相关推荐
lisin-lee-cooper1 小时前
简单聊聊 Spring 框架源码
java·后端·spring
kyriewen1 小时前
AI 改祖传模块后,代码评审总绕不开两个问题
前端·程序员·ai编程
一木 之林1 小时前
七、一-AI 工程实践、插件化调试与软件交付
java·linux·c++
边境悍匪1 小时前
蜗牛学苑 Java 智能体学习 Day38|Spring AI Alibaba2 思维导图复盘
java·学习·spring
飞翔的熊blabla1 小时前
# Webpack 5 + Jenkins 持久化缓存实战:前端构建从 288 秒降到 30 秒>
前端·webpack·jenkins
风骏时光牛马2 小时前
AI多模态:跨越感官边界的智能新体验 要不要开启工作任务模式,帮你配套对应的文案和配图思路?
前端
Co_Hui2 小时前
Java 静态内部类、非静态内部类、匿名内部类的区别?
java
IT_陈寒2 小时前
JavaScript的这个隐式转换特性差点让我加班到凌晨
前端·人工智能·后端
Wang's Blog2 小时前
Java框架快速入门: Spring Security+OAuth2之自定义认证过滤器实现JSON登录
java·spring·json