JavaScript---DOM---节点操作---12.3

news2024/9/28 13:19:08

为什么学节点操作?

获取元素通常使用两种方式:

1.利用DOM提供的方法获取元素

  • document.getElementByld()
  • document.getElementsByTagName()
  • document.querySelector等
  • 逻辑性不强,繁琐

2.利用节点层级关系获取元素(操作更简单)

  • 利用父子兄节点关系获取元素
  • 逻辑性强,但是兼容性稍差

节点概述

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

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

  • 元素节点nodeType为1
  • 属性节点nodeType为2
  • 文本节点nodeType为3(文本节点包含文字、空格、换行等)

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

节点层级

利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄层级关系

父级节点:node.parentNode

<div class="box">
    <span class="erweima">×</span>
</div>
<script>
    var erweima = document.querySelector('.erweima');
    erweima.parentNode;//parentNode属性返回某节点的最近的一个父节点
                       //如果指定的节点没有父节点,则返回null
    console.log(erweima.parentNode);
</script>

子级节点

1.parentNode.childNodes(标准)

parentNode.childNodes返回包含指定节点的子节点的集合,该集合为即时更新的集合。

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

var ul = document.queryselector('ul');
for(var i=0;i<ul.childNodes.length;i++) {
     if (ul.childNodes[i].nodeType == 1) {
          //ul.childNodes[i]是元素节点
          console.log(ul.childNodes[i]);

     }

}

2.parentNode.children(非标准)

parentNode.children是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回。这个是我们重点掌握的!!!!!
虽然children是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用。

<ul>
    <li></li>
    <li></li>
</ul>
<script>
    var ul = document.querySelector('ul');
    ul.children;
    console.log(ul.children);
</script>

3.parentNode.firstChild

firstChild返回第一个子节点,找不到侧返回null。同样,也是包含所有的节点。

4.parentNode.lastChild

lastChild返回最后一个子节点,找不到则返回null。同样,也是包含所有的节点。

5.parentNode.firstElementChild

firstElementchild返回第一个子元素节点,找不到则返回null。

6.parentNode.lastElementChild
lastElementChild返回最后一个子元素节点,找不到则返回null。

<ol>
   <li>我是1</li>
   <li>我是2</li>
   <li>我是3</li>
   <li>我是4</li>
</ol>
<script>
   var ol = document.querySelector('ol');
   ol.firstElementChild;
   console.log(ol.firstElementChild);
   console.log(ol.lastElementChild);
</script>

案例:下拉菜单

<style>
    * {padding: 0;margin: 0;list-style: none;}
    .nav>li {
        position: relative;float: left;
        width: 80px;height: 41px;text-align: center;
    }
    .nav li a {
        display: block;width: 100%;height: 100%;
        line-height: 41px;text-decoration: none;color: black;
    }
    .nav>li>a:hover {background-color: pink;}
    .nav ul {
        display: none;position: absolute;top: 41px;left: 0;
        width: 100%;border-left: 1px solid skyblue;
        border-right: 1px solid skyblue;
    }
    .nav ul li {border-bottom: 1px solid skyblue;}
    .nav ul li:hover {background-color: skyblue;}
</style>

<ul class="nav">
    <li>
        <a href="#">微博</a>
        <ul><li><a href="#">私信</a></li>
            <li><a href="#">评论</a></li>
        </ul>
    </li>
    <li>
        <a href="#">微博</a>
        <ul><li><a href="#">私信</a></li>
            <li><a href="#">评论</a></li>
        </ul>
    </li>
</ul>

<script>
    var nav = document.querySelector('.nav');
    var lis = nav.children;
    for(var i=0; i<lis.length; i++) {
        lis[i].onmouseover = function() {
            this.children[1].style.display = 'block';
        }
        lis[i].onmouseout = function() {
            this.children[1].style.display = 'none';
        }
    }
</script>

兄弟节点

1.node.nextSibling

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

2.node.previousSibling

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

3.node.nextElementSibling

nextElementSibling返回当前元素的下一个兄弟元素节点,找不到则返回null。

4.node.previousElementSibling

previousElementSibling返回当前元素的上一个兄弟元素节点,找不到则返回null。

<div>我是div</div>
<span>我是span</span>
<script>
    var div = document.querySelector('div');
    div.nextSibling;
    console.log(div.nextElementSibling);
</script>

创建添加节点

创建节点

document.createElement('tagName')

此方法创建由tagName指定的HTML元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点

添加节点

1.node.appendChild(child)

此方法将一个节点添加到指定父节点的子节点列表末尾,类似于css里面的after伪元素。

<ul><li>1234</li></ul>
<script>
    var ul = document.querySelector('ul');
    var li = document.createElement('li');
    ul.appendChild(li);
</script>

2.node.insertBefore(child,指定元素)

此方法将一个节点添加到父节点的指定子节点前面。类似于css里面的before伪元素。

<ul><li>1234</li></ul>
<script>
    var ul = document.querySelector('ul');
    var lii = document.createElement('li');
    ul.insertBefore(lii,ul.children[0]);
</script>

案例:简单版发布留言案例

<textarea name="" id="" cols="30" rows="10"></textarea>
<button>发布</button>
<ul> <li>123</li> </ul>
<script>
    var btn = document.querySelector('button');
    var text = document.querySelector('textarea');
    var ul = document.querySelector('ul');
    btn.onclick = function() {
        if(text.value == '') {
            alert('您没有输入内容');
            return false;
        } else {
            var li = document.createElement('li');
            li.innerHTML = text.value;
            ul.insertBefore(li,ul.children[0]);
        }
    }
</script>

删除节点

node.removeChild(child)

此方法从DOM中删除一个子节点,返回删除的节点。

<button>删除</button>
<ul> <li>11</li> <li>22</li> <li>33</li> </ul>
<script>
    var ul = document.querySelector('ul');
    var btn = document.querySelector('button');
    btn.onclick = function() {
        if(ul.children.length == 0) {
            this.disabled = true;
        }else {
            ul.removeChild(ul.children[0]);
        }
    }
</script>

案例:简单版删除留言案例

<textarea name="" id="" cols="30" rows="10"></textarea>
<button>发布</button>
<ul> <li>123</li> </ul>
<script>
    var btn = document.querySelector('button');
    var text = document.querySelector('textarea');
    var ul = document.querySelector('ul');
    btn.onclick = function() {
        if(text.value == '') {
            alert('您没有输入内容');
            return false;
        } else {
            var li = document.createElement('li');
            li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
            ul.insertBefore(li,ul.children[0]);
            var as = document.querySelectorAll('a');
            for(var i=0; i<as.length; i++) {
                as[i].onclick = function() {
                    ul.removeChild(this.parentNode);//当前a所在的li就是this.parentNode
                }
            }
        }
    }
</script>

复制节点(克隆节点)

node.cloneNode()

此方法返回调用该方法的节点的一个副本。也称为克隆节点/拷贝节点。

  • 如果cloneNode()参数为空或false,则为浅拷贝,只复制节点本身,不复制子节点(内容)。
  • 如果cloneNode()参数为true,则为深度拷贝,会复制节点本身以及里面的所有子节点。
<ul> <li>1</li> <li>2</li> <li>3</li> </ul>
<script>
    var ul = document.querySelector('ul');
    var lii = ul.children[0].cloneNode(true);
    ul.appendChild(lii);
</script>

案例:动态生成表格

<style>
    table {width: 500px;border-collapse: collapse;text-align: center;}
    td,th {border: 1px solid #333;}
    thead tr {height: 40px;background-color: #ccc;}
</style>

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

<script>
    var datas = [
        {name:'陈亚婷',subject:'JavaScript',score:'100'},
        {name:'赵飞帆',subject:'JavaScript',score:'99' },
        {name:'张三三',subject:'JavaScript',score:'88' }
    ];
    // 创建tbody的行
    var tbody = document.querySelector('tbody');
    for(var i=0; i<datas.length; i++) {
        var tr = document.createElement('tr');
        tbody.appendChild(tr);
        for(var k in datas[i]) {  //for…in 用于对数组或者对象的属性进行循环操作
            //创建单元格
            var td = document.createElement('td');
            td.innerHTML = datas[i][k];
            tr.appendChild(td);
        }
        var td = document.createElement('td');
        td.innerHTML = '<a href="javascript:;">删除</a>';
        tr.appendChild(td);
    }
    var as = document.querySelectorAll('a');
    for(var i=0; i<as.length; i++) {
        as[i].onclick = function() {
            tbody.removeChild(this.parentNode.parentNode);
        }
    }
</script>

三种动态创建元素区别

document.write()  了解即可

直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘。

element.innerHTML   效率高

将内容写入某个DOM节点,不会导致页面全部重绘。创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂。

document.createElement()   效率低

创建多个元素效率稍低一点点,但是结构更清晰。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/139530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

标准模板库STL

一、概述 1.1 STL的概念和作用 STL的概念&#xff1a;全称为 Standard Template Library STL的作用&#xff1a; 首先STL并不是语言的一部分&#xff08;一开始并没有&#xff09;它就是一个工具库, 没有这个工具时程序员写程序都要自己做&#xff08;例如&#xff1a;数据结…

软件生命周期阶段有几个?常见软件生命周期模型有哪些?

软件生命周期阶段及常见的软件生命周期模型&#xff0c;软件生命周期是指一个计算机软件从功能确定、设计&#xff0c;到开发 成功投入使用&#xff0c;并在使用中不断地修改、增补和完善&#xff0c;直到停止该软件的使用的全过程。  生命周期从收到应用软件开始算起&#x…

springboot 多模块项目构建【创建√ + 启动√ 】

一、多模块项目构建 1. 先建立父级目录demo-parent 2. 把父级目录src删除&#xff0c;再建立子级模块 3. 建立子级模块model,dao,service,common.utils等相同步骤 4. 建立启动模块boot, 创建Spring Boot 启动类 package com.example;import org.springframework.boot.SpringAp…

http服务转https服务(Nginx 服务器 SSL 证书安装部署)

安装的服务一直使用的是http&#xff0c;结果有客户要求必需使用https,下面是整理的步骤1、证书下载&#xff1a;&#xff08;要用域名申请的账号登录&#xff09;域名所在服务商一般都可以下载免费证书&#xff0c;我们用的域名是腾讯云的&#xff0c;所以在腾讯云上申请了免费…

高通开发系列 - gpio模拟输出PWM或者CLK时钟

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 问题背景平台信息GPIO输出CLKdts添加节点修改内核gcc时钟配置驱动文件编译运行gpio模拟PWM输出CLKdts中的配置GPIO模拟PWM驱动文件编译…

MSF信息收集

Nmap扫描 db_nmap -sV 192.168.1.0/24Auxiliary 扫描模块 ● RHOSTS表示 192.168.1.20-192.168.1.30 、 192.168.1.0/24,192.168.11.0/24&#xff08;扫描两个网段&#xff09; file:/root/host.txt (将需要扫描的主机访问文本中)● search arp use auxiliary/scanner/d…

网站收录查询方法,网站收录减少的原因

网站收录就是与互联网用户共享网址&#xff0c;网站收录前提是网站首页提交给搜索引擎&#xff0c;蜘蛛才会光顾&#xff0c;每次抓取网页时都会向索引中添加并更新新的网站&#xff0c;站长只需提供顶层网页即可&#xff0c;不必提交各个单独的网页。抓取工具能够找到其他网页…

华为matebook X 笔记本没开什么程序,有时经常慢卡

环境&#xff1a; 华为matebook X CPU &#xff1a;英特尔4核8线程10代 i5 内存&#xff1a;海力士16G 固态硬盘500G 问题描述&#xff1a; 华为matebook X 没开什么程序&#xff0c;经常慢卡&#xff0c;平时就是打开钉钉&#xff0c;处理处理文档&#xff0c;之前优化过…

模板题---1.5(单调栈,单调队列,kmp,manachar)

这里写目录标题1.单调栈2.单调队列3.kmp算法4.manachar算法这里记录几个基本的数据结构算法1.单调栈 要点&#xff1a; 数据结构是栈栈要维护单调性 这就是单调栈的基本定义 举个例子: &#xff08;栈底&#xff09;1 3 5 7 &#xff08;栈顶&#xff09; <-------这就是…

行为型模式 - 备忘录模式Memento

学习而来&#xff0c;代码是自己敲的。也有些自己的理解在里边&#xff0c;有问题希望大家指出。 模式的定义与特点 在备忘录模式&#xff08;Memento Pattern&#xff09;下&#xff0c;为的是在不破坏封装性的前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在该对象…

【C++ Primer】阅读笔记(2):const | constexpr | 类型别名 |auto

目录 简介const指针顶层const与底层const常量表达式constexpr类型别名auto参考结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过…

CTF中的PHP特性函数(下)

前言 上篇文章讲的进阶一些的PHP特性不知道大家吸收的怎么样了&#xff0c;今天作为本PHP特性函数的最后一篇&#xff0c;我也会重点介绍一些有趣的PHP特性以及利用方法&#xff0c;下面开始我们今天的内容分享。 parse_str parse_str()这个函数会把查询字符串解析到变量中。…

二叉树——链式存储

✅<1>主页&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;数据结构——二叉树 &#x1f525;<3>创作者&#xff1a;我的代码爱吃辣 ☂️<4>开发环境&#xff1a;Visual Studio 2022 &#x1f4ac;<5>前言&#xff1a;上期讲了…

LinkedList与链表(一)(非循环单向链表)

ArrayList的缺陷通过ArrayList上节课的学习&#xff0c;我们了解到如果ArrayList要删除或插入一个元素&#xff0c;后面的元素都要进行移动&#xff0c;时间复杂度为O(n),效率比较低&#xff0c;因此ArrayList不适合做任意位置的插入和删除操作比较多的场景。因此java集合又引入…

Python if __name__ == “__main__“ 用法

文章目录1 前言2 原理3 __name__变量的作用参考1 前言 在很多Python程序中&#xff0c;我们都会遇到if __name__ "__main__"的情况&#xff0c;却不知道为何要这样做 在很多编程语言中&#xff0c;如C、Java等&#xff0c;都需要程序的入口&#xff0c;一般都是ma…

MySql锁机制(全网最全、最详细、最清晰)

1、MySql锁机制 锁机制的作用&#xff1a; 解决因为资源共享&#xff0c;而造成的并发问题。 没有锁机制时&#xff1a; 例如一号用户和二号用户都要去买同一件商品&#xff08;假如这件商品是一件衣服&#xff09;&#xff0c;一号用户手速稍微快了一些&#xff0c;于是就…

从事软件测试需要学自动化么

相信许多对软件测试有过一点了解的人&#xff0c;对自动化都不会感到陌生。我们常常会听到一定软件测试人员一定要学自动化的说法&#xff0c;那么很多人都会有这样的疑问&#xff0c;从事软件测试为什么要学自动化&#xff1f;事实上&#xff0c;如今只会功能测试的从业者往往…

光波导成为AR眼镜迭代新趋势,二维扩瞳几何光波导潜力彰显

关注AR眼镜的朋友可能都会发现&#xff0c;近期新品迭代的一个趋势是持续在小型化、轻量化方向演进。与一年前光学方案主要以BirdBath不同的是&#xff0c;消费级AR眼镜正快速向光波导方案探索和转变。这一点在最近发布的众多新品AR眼镜中就能明显的感受到&#xff0c;以视享G5…

堆排序 TopK 优先级队列的部分源码 JAVA对象的比较

一.堆排序:我们该如何借助堆来对数组的内容来进行排序呢&#xff1f; 假设我们现在有一个数组&#xff0c;要求从小到大进行排序&#xff0c;我们是需要进行建立一个大堆还是建立一个小堆呢&#xff1f; 1)我的第一步的思路就是建立一个小堆&#xff0c;因为每一次堆顶上面的元…

MGRE和ospf的综合运用

目录实验需求知识点实验过程一&#xff0c;在R1 R2 R3中的MGRE搭建二&#xff0c;在R1 R4 R5中的MGRE搭建三&#xff0c;整个内网的ospf协议实验需求 一 题目要求 1&#xff0c;R6为ISP代表运营商&#xff0c;只能配置ip地址&#xff0c;R1-R5环回 代表私有网段 2&#xff0c…