DOM(文档对象模型)(二)深入了解DOM节点

本文详细介绍了DOM(文档对象模型)中的节点操作,包括通过节点关系获取节点、创建节点、插入节点、删除节点、替换节点和克隆节点等。内容涵盖节点的属性、各种API的使用示例,如appendChild、insertBefore、removeChild等,以及实际应用中的表格操作和选项卡小案例。


前言

       在学习CSS时,可以把上面的每一个标签看成一个盒子。
       在学习DOM时,可以把上面的每一个标签看成一个节点(DOM节点,DOM元素,DOM对象)。
       页面中的每一个部分,都是节点。

  1. document: 一个页面中最大的节点,只能有一个,承载所有节点的容器。根节点。不是元素节点.
  2. html :最大的元素节点,html节点中又包含了很多的节点。
  3. 其它的元素节点:head / body / div / ul / table / input …
  4. 文本节点:一个标签中可以包含一个文本,这个文本叫文本节点,包含换行和空格。
  5. 文本节点:一般也是元素节点的子节点。
  6. 属性节点:属性节点不能单独存在,必须依赖元素节点,要得到属性节点,先得到元素节点。DOM树,在DOM树上,是没有属性节点,DOM树上有很多的节点,我们只需要掌握元素节点和文本节点…
  7. 注释节点 :作为一个独立的点的出现的,为说明使用。

对元素节点的操作

  1. 获取:上篇文章中介绍了9种方式,还有一种是通过节点关系来获取节点。
  2. 创建节点: 通过JS中的一个api就可以创建元素节点(1)createElement() ,(2)createTextNode(),(3) createComment() ,(4)createAttribute()。
  3. 插入节点:当我们创建出一个节点后,这个节点并没有出现在DOM树上,我们需要手动插入到DOM树上。(1)appendChild(),(2)insertBefore()。
  4. 删除节点 :把某个节点,从DOM树上移除掉(1)removeChild() ,(2)remove()。
  5. 替换节点: replaceChild()。
  6. 克隆节点:把一个已经存在的节点,复制一份一模一样的。语法:cloneNode(参数) ,如果参数是true,表示深clone,如果参数是false,表示浅clone。

提示:以下是本篇文章正文内容,下面案例可供参考

一、通过节点关系获取节点

引入:

问: 下面的代码中,div标签中有多少个子(儿子)节点?

     <div id="box" class="abc" index="hello world~">
        hello 
        <p>你好</p>
        world
        <p>世界</p>
        <!-- 我是一段注释 -->
     </div>

答: 七个。
       1)文本节点:(1个换行,四个空格,一个hello,一个换行,四个空格)
       2)元素节点(p标签)
       3)文本节点:(1个换行,四个空格,一个world,一个换行,四个空格)
       4)元素节点(p标签)
       5)文本节点:(1个换行,四个空格)
       6) 注释节点
       7)文本节点:(1个换行)

1.childNodes 得到所有的子节点

	<!-- 1)childNodes  得到所有的子节点   是一个伪数组 -->
    <script>
        let div = document.querySelector("div")
        console.log(div.childNodes);
    </script>

结果如下:
在这里插入图片描述

2.children 得到所有元素节点

	<!-- 2)children  得到所有元素节点 -->
    <script>
        let div = document.querySelector("div")
        console.log(div.children);
    </script>

结果如下:
在这里插入图片描述

3.firstChild 得到第一个子节点

	<!-- 3)firstChild 得到第一个子节点 -->
    <script>
        let div = document.querySelector("div")
        console.log(div.firstChild);
    </script>

结果如下:
在这里插入图片描述

4.firstElementChild 得到第一个元素节点

	<!-- 4)firstElementChild  得到第一个元素节点 -->
    <script>
        let div = document.querySelector("div")
        console.log(div.firstElementChild);
    </script>

结果如下:
在这里插入图片描述

5.lastChild 得到最后一个子节点

	<!-- 5)lastChild 得到最后一个子节点 -->
    <script>
        let div = document.querySelector("div")
        console.log(div.lastChild);
    </script>

结果如下:
在这里插入图片描述

6.lastElementChild 得到最后一个元素节点

	<!-- 6)lastElementChild 得到最后一个元素节点 -->
    <script>
        let div = document.querySelector("div")
        console.log(div.lastElementChild);
    </script>

结果如下:
在这里插入图片描述

7.proviousSibling 得到上一个兄弟节点

	<!-- 7)proviousSibling 得到上一个兄弟节点(哥哥节点) -->
    <script>
        let div = document.querySelector("div")
        console.log(div.previousSibling);
    </script><!-- 2)children  得到所有元素节点 -->
    <script>
        let div = document.querySelector("div")
        console.log(div.children);
    </script>

结果如下:
在这里插入图片描述

8.proviousElementSibling 得到上一个兄弟元素节点

	<!-- 8)proviousElementSibling 得到上一个兄弟元素节点(哥哥元素节点) -->
    <script>
        let div = document.querySelector("div")
        console.log(div.previousElementSibling);
    </script>

结果如下:
在这里插入图片描述

9.nextSibling 得到下一个兄弟节点

	<!-- 9)nextSibling 得到下一个兄弟节点(弟弟节点) -->
    <script>
        let div = document.querySelector("div")
        console.log(div.nextSibling);
    </script>

结果如下:
在这里插入图片描述

10.nextElementSibling 得到下一个兄弟元素节点

	<!--  10)nextElementSibling 得到下一个兄弟元素节点(弟弟元素节点) -->
    <script>
        let div = document.querySelector("div")
        console.log(div.nextElementSibling);
    </script>

结果如下:
在这里插入图片描述

11.parentNode 得到父节点,得到的都是元素节点

	<!--  11)parentNode 得到父节点,得到的都是元素节点  特别需要注释  document-->
    <script>
        let div = document.querySelector("div")
        console.log(div.parentNode);
    </script>

结果如下:
在这里插入图片描述

12.parentElement 得到父元素节点

	<!-- 12) parentElement 得到父元素节点 -->
    <script>
        let div = document.querySelector("div")
        console.log(div.parentElement);
    </script>

结果同上:
在这里插入图片描述

13.attributes 得到元素的所有属性节点

	<!-- 13)attributes 得到元素的所有属性节点 -->
    <script>
        let div = document.querySelector("div")
        console.log(div.attributes);
    </script>

结果如下:
在这里插入图片描述

二、节点的属性

(1)nodeType 就是一个编号
       以数字的形式来表示一个节点的类型
              元素节点:1
              属性节点:2
              文本节点:3
              注释节点:8
(2)nodeName
              节点的名字 标签全大写 DIV #text #comment
(4)nodeValue
       节点的值
              元素节点的值:null
              属性节点的值:对应的属性值
              文本节点的值:文本内容 包含换行和空格
              注释节点的值:注释内容 包含换行 和 空格

    <div id="box" class="container">
        <!-- 你好世界 -->
        Hello World
    </div>
    <script>
        

        // 元素节点
        let div=document.getElementById("box");
        console.log("元素节点-------------------------------------");
        console.log(div);
        console.log(div.nodeType);//1
        console.log(div.nodeName);//DIV
        console.log(div.nodeValue);//null

        // 属性节点
        let attr=div.attributes[0];
        console.log("属性节点-------------------------------------");
        console.log(attr);//id="box"
        console.log(attr.nodeType);//2
        console.log(attr.nodeName);//id
        console.log(attr.nodeValue);//box

         // 文本节点
        let text=div.childNodes[2];
        console.log("文本节点-------------------------------------");
        console.log(text);//"     Hello World    "
        console.log(text.nodeType);//3
        console.log(text.nodeName);//#text
        console.log(text.nodeValue); //Hello World

         // 注释节点
        let comment=div.childNodes[1];
        console.log("注释节点-------------------------------------");
        console.log(comment);//<!-- 你好世界 -->
        console.log(comment.nodeType);//8
        console.log(comment.nodeName);//#comment
        console.log(comment.nodeValue);//你好世界
        
    </script>

结果如下:
在这里插入图片描述

三、创建节点

创建节点:
       通过JS中的一个api就可以创建元素节点
              createElement() 创建元素节点
              createTextNode() 创建文本节点
              createComment() 创建注释节点
              createAttribute() 创建属性节点

	<script>
        // 创建元素节点
        console.log("元素节点---------------------");
        let div=document.createElement("div");
        console.log(div);

        // 创建文本节点
        console.log("文本节点---------------------");
        let text=document.createTextNode("hello world~")
        console.log(text);

        // 创建注释节点
        console.log("注释节点---------------------");
        let comment=document.createComment("我是一行注释");
        console.log(comment);

        // 创建属性节点
        console.log("属性节点---------------------");
        let attr=document.createAttribute("id");
        attr.value="box";
        console.log(attr);
    </script>

结果如下:
在这里插入图片描述

四、插入节点

       当我们创建出一个节点后,这个节点并没有出现在DOM树上,我们需要手动插入到DOM树上。

(1)appendChild()
       父节点.appendChild(子节点) 把一个子点插入到一个父节点的最后面的
(2)insertBefore()
       父节点.insertBefore(要插入的节点,哪一个节点的前面)

 	<div class="box">
        <p>我是div里面的p标签</p>
    </div>

    <script>
        let div=document.querySelector("div")
        let p=document.querySelector("p")

        // 创建一个span节点
        let span =document.createElement("span")
        span.innerHTML="我是新来的span节点"

        // 再创建一个节点
        let h1=document.createElement("h1")

        // 把span节点插入到div里
        div.appendChild(span);

        // 把h1节点插入到span节点里 再把span节点插入到div里
        // span.appendChild(h1);
        // div.appendChild(span)

        // 把span节点插入到h1里,把h1插入到p标签前面
        h1.appendChild(span);
        div.insertBefore(h1,p)
    </script>

结果如下:
在这里插入图片描述

五、删除节点

       删除节点:把某个节点,从DOM树上移除掉。
       (1)removeChild()
              父节点.removeChild(子节点) 把子节点从父节点中删除掉
       (2)remove()
              节点.remove() 把自己移出父节点

	<div>
        <p>我是div里面的p标签</p>
    </div>
    <script>
        let div=document.querySelector("div")
        let p=document.querySelector("p")

        // 把p标签从div里面删除掉
        div.remove(p) //删除子节点

        // 把div从body中移除掉
        div.remove() //删除自己
    </script>

结果如下:
在这里插入图片描述

六、替换节点

       replaceChild()
              父节点.replaceChild(新节点,旧节点)

	<div>
        <p>我是div里面的p标签</p>
    </div>
    <script>
        let div=document.querySelector("div")
        let p=document.querySelector("p")

        // 创建一个span节点
        let span=document.createElement("span");
        span.innerHTML="我是新来的span节点";

        // 替换
        div.replaceChild(span,p)
		
		// 替换的另一种方法
		// div.replaceChild(span,div.firstElementChild)
    </script>

结果如下:
在这里插入图片描述

七、克隆节点

       把一个已经存在的节点,复制一份一模一样的
       cloneNode(参数)
              如果参数是true,表示深clone
              如果参数是false,表示浅clone

	<div class="box" id="box">
        <button>按钮</button>
    </div>
    <hr>
    <script>
        let div=document.querySelector("div");
        let cloneDiv=div.cloneNode(true);//深克隆 包括克隆的对象的子节点
        console.log(cloneDiv);

        // let cloneDiv1=div.cloneNode(false);//浅克隆 仅包括克隆对象本身  不包括子节点
        // console.log(cloneDiv1);
    </script>

深克隆结果如下:
在这里插入图片描述

浅克隆结果如下:
在这里插入图片描述

八、带有添加和删除功能的表格

<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset='UTF-8'>
    <title>Document</title>
    <style>
        *{
            margin: 0; padding: 0;
        }
        form{
            width: 300px;
            padding: 20px;
            margin: 10px auto;
            border: 10px solid skyblue;
        }
        form button{
            width: 100%;
            height: 30px;
            margin: 10px 0;
        }
        table{
            border: 2px solid pink;
            width: 500px;
            margin: 10px auto;
            text-align: center;
        }
        table tr{
            height: 38px;
        }
        table tbody tr:nth-child(odd){
            background-color: #ccc;
        }
        table tbody tr:nth-child(even){
            background-color: orange;
        }
    </style>
</head>
<body>
        
    <!-- 
        
     -->
     <form action="">
         姓名:<input type="text" class="username"> <br>
         年龄:<input type="text" class="userage"> <br>
         性别:<input type="text" class="usergender"> <br>
         <button type="button" class="add">添加</button>
     </form>
     <table cellspacing="0">
         <thead>
             <tr>
                 <th>姓名</th>
                 <th>年龄</th>
                 <th>性别</th>
                 <th>操作</th>
             </tr>
         </thead>
         <tbody>
             <tr>
                 <td>张三</td>
                 <td>10</td>
                 <td></td>
                 <td>
                     <button class="del">删除</button>
                 </td>
             </tr>
             <tr>
                <td>李四</td>
                <td>20</td>
                <td></td>
                <td>
                    <button class="del">删除</button>
                </td>
            </tr>
            <tr>
                <td>王五</td>
                <td>18</td>
                <td></td>
                <td>
                    <button class="del">删除</button>
                </td>
            </tr>
         </tbody>
     </table>
    <script>
        let add=document.querySelector(".add");
        let tbody=document.querySelector("tbody")
        let nameIpt=document.getElementsByTagName("input")[0];
        let ageIpt=document.getElementsByTagName("input")[1];
        let generIpt=document.getElementsByTagName("input")[2];
        let dels=document.querySelectorAll(".del")
        
        // 给添加按钮注册点击事件
        add.onclick=function(){
            let nameValue=nameIpt.value;
            let ageValue=ageIpt.value;
            let generValue=generIpt.value;

            // trim表示去掉字符串两侧的空格
            if(nameValue.trim()===""||ageValue.trim()===""||generValue.trim()===""){
                alert("输入值不能为空!")
                return;//结束程序
            }

            // 字符串中有内容  先创建节点
            let tr=document.createElement("tr");
            let td1=document.createElement("td")
            let td2=document.createElement("td")
            let td3=document.createElement("td")
            let td4=document.createElement("td")
            let button=document.createElement("button")

            td1.innerHTML=nameValue;
            td2.innerHTML=ageValue;
            td3.innerHTML=gennerValue;
            button.innerHTML="删除"

            // 给删除按钮绑定点击事件
            button.onclick=function(){
                let tr=this.parentElement.parentElement;
                tr.remove();
            }

            tr.appendChild(td1);
            tr.appendChild(td2);
            tr.appendChild(td3);
            td4.appendChild(button);
            tr.appendChild(td4);

            tbody.appendChild(tr)

            // 清空输入框
            nameIpt.value="";
            ageIpt.value="";
            generIpt.value="";
        }
            
        // 给删除按钮绑定点击事件
        // 通过添加按钮添加的数据并没有绑定点击事件
        // 解决方法:在创建tr时直接绑定点击事件
        dels.forEach(item=>{
            item.onclick=function(){
                let tr=this.parentElement.parentElement;
                tr.remove();
            }
        })

            
    </script>
</body>
</html>

输入数据,结果如下:

在这里插入图片描述
点击添加按钮,结果如下:
在这里插入图片描述

九、根据数据创建一个表格

<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset='UTF-8'>
    <title>Document</title>
</head>
<body>
    <table border="1" cellspacing="0">
        <thead>
            <tr>
                <th>姓名</th>
                <th>年龄</th>
                <th>性别</th>
            </tr>
        </thead>
        <tbody>
            
        </tbody>
    </table>
    <script>
        var userList = [
            { name:"彭万里",age:100,gender:"男" },
            { name:"高大山",age:110,gender:"女" },
            { name:"谢大海",age:109,gender:"男" },
            { name:"马宏宇",age:118,gender:"女" },
            { name:"林莽",age:90,gender:"男" },
        ];

        // 得到tbody
        let tbody =document.querySelector("tbody");

        // 创建一个存放数据的容器 也叫文档碎片
        let frg=document.createDocumentFragment();
        userList.forEach(item=>{
            let tr=document.createElement("tr")
            tr.innerHTML=`
                <td>${item.name}</td>
                <td>${item.age}</td>
                <td>${item.gender}</td>
            `
            frg.appendChild(tr)
        })

        tbody.appendChild(frg)
    </script>
</body>
</html>

结果如下:
在这里插入图片描述

十、tab选项卡小案例

目的:鼠标点击哪个li,哪个li被选中(背景颜色橙色),并且显示对应的内容。

<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset='UTF-8'>
    <title>Document</title>
    <style>
        *{
            margin: 0; 
            padding: 0;
        }
        ul,ol,li{
            list-style: none;
        }
        .box{
            width: 600px;
            height: 400px;
            border: 1px solid #333;
            margin: 50px auto;
        }
        .box ul{
            height: 50px;
            width: 100%;
        }
        .box ul li{
            float: left;
            width: 199px;
            height: 100%;
            border-right: 1px solid #333;
            text-align: center;
            line-height: 50px;
            font-size: 30px;
            background-color: skyblue;
            color: #fff;
            cursor: pointer;
        }
        .box ul li.active{
            background-color: orange;
        }
        .box ol{
            width: 100%;
            height: 350px;
        }
        .box ol li{
            width: 100%;
            height: 100%;
            background-color: purple;
            text-align: center;
            line-height: 350px;
            font-size: 100px;
            color: #fff;

            /* 全部隐藏掉 */
            display: none;
        }
        .box ol li.active{
            display: block;
        }
    </style>
</head>
<body>
    <div class="box">
        <ul>
            <li class="active">1</li>
            <li>2</li>
            <li style="border-right: 0px solid #333; width:200px;">3</li>
        </ul>
        <ol>
            <li class="active">1</li>
            <li>2</li>
            <li>3</li>
        </ol>
    </div>

    <script>
        let btns=document.querySelectorAll("ul li");
        let tabs=document.querySelectorAll("ol li");

        // 利用for循环给btns添加点击事件
        btns.forEach(function(item,index){
            // 给每个ul下面的li添加一个自定义属性,叫index
            // 值是对应索引
            btns[index].setAttribute("index",index)
            
            item.onclick=function(){
                // console.log(this);

                // 先把ul下面的所有li的类名去掉  一刀切
                for(var j=0;j<btns.length;j++){
                    btns[j].className="";
                    tabs[j].className="";
                }
                // this.表示 item事件源
                this.className="active"

                // 让对应的tabs显示出来
                let index=this.getAttribute("index");
                tabs[index].className="active"
            }
        })
    </script>
</body>
</html>

结果如下:
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值