【DOM笔记三】节点操作(节点概述、节点层级、添加 / 删除 / 复制节点、DOM基本语法总结!

文章目录

    • 5 节点操作
      • 5.1 节点概述
      • 5.2 节点层级
        • 5.2.1 父子节点
        • 5.2.2 兄弟节点
      • 5.3 添加元素
      • 5.4 删除节点
      • 5.5 复制节点
      • 5.6 三种动态创建元素的区别
    • 6 DOM小结

5 节点操作

获取元素的方式:

【DOM笔记三】节点操作(节点概述、节点层级、添加 / 删除 / 复制节点、DOM基本语法总结!_第1张图片

比较发现,用节点层级关系来获取元素更简单(DOM方法相当于绝对路径,节点方法相当于相对路径)。

5.1 节点概述

概念: 网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM中,节点使用node来表示。

基本组成: nodeType(节点类型) 、nodeName(节点名称)、nodeValue(节点值)

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

节点操作(主要为元素节点)的目的: 获取元素

5.2 节点层级

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

5.2.1 父子节点
【DOM笔记三】节点操作(节点概述、节点层级、添加 / 删除 / 复制节点、DOM基本语法总结!_第2张图片

1.父节点

  • node.parentNode

2.子节点

  • node.childNodes(标准),返回子节点(元素节点、文本节点…)集合
  • node.children(非标准),返回子元素节点集合(各浏览器都支持,更常用
  • node.firstChild,返回第一个子节点(所有类型),找不到返回null
  • node.lastChild,返回最后一个子节点(所有类型)
  • node.firstElementChild,返回第一个子元素节点,IE9以上才支持
  • node.lastElementChild,返回最后一个子元素节点,IE9以上才支持
  • node.children[0],返回第一个子元素节点,没有兼容性问题
  • node.children[ol.children.length - 1]),返回ol最后一个子元素节点,没有兼容性问题
DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
head>

<body>
    
    <div>我是divdiv>
    <span>我是spanspan>
    <ul>
        <li>我是lili>
        <li>我是lili>
        <li>我是lili>
        <li>我是lili>
    ul>
    <ol>
        <li>我是li1li>
        <li>我是li2li>
        <li>我是li3li>
        <li>我是li4li>
    ol>
    
    <div class="demo">
        <div class="box">
            <span class="erweima">×span>
        div>
    div>
    
    <script>
        // DOM 提供的方法(API)获取 '父节点'
        var erweima = document.querySelector('.erweima');
        var box = document.querySelector('.box');  // 以前获得.box方法
        // 父节点 node.parentNode
        console.log(erweima.parentNode);   // 现在获得.box方法为erweima.parentNode,返回
...
,得到的是离元素最近的父级节点(亲爸爸)box,得不到demo,如果找不到父节点就返回为 null
// DOM 提供的方法(API)获取 '子节点' var ul = document.querySelector('ul'); var lis = ul.querySelectorAll('li'); // 1. node.childNodes 获得所有的子节点,包含:元素节点、文本节点... console.log(ul.childNodes); // NodeList(9) console.log(ul.childNodes[0].nodeType); // 3(文本节点) console.log(ul.childNodes[1].nodeType); // 1(元素节点) // 如何只获取元素节点? var ul = document.queryselector ('ul'); for(var i = 0; i < ul.childNodes.length; i++) { if (ul.childNodes[i].nodeType == 1) { console.log (ul.childNodes[i]); // ul.childNodes[i]是元素节点 } } // 这种方法太麻烦,因此用方法2 // 2. node.children 获取所有的子元素节点,更常用 console.log(ul.children); // HTMLCollection(4) var ol = document.querySelector('ol'); // 3.4. node.firstChild console.log(ol.firstChild); // #text console.log(ol.lastChild); // #text // 5.6. node.firstElementChild,IE9以上才支持 console.log(ol.firstElementChild); //
  • 我是li1
  • console.log(ol.lastElementChild); //
  • 我是li4
  • // 7.8. node.children[0]实际开发的写法,没有兼容性问题 console.log(ol.children[0]); //
  • 我是li1
  • console.log(ol.children[ol.children.length - 1]); //
  • 我是li4
  • script> body> html>

    案例:下拉菜单

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            
            li {
                list-style-type: none;
            }
            
            a {
                text-decoration: none;
                font-size: 14px;
            }
            
            .nav {
                margin: 100px;
            }
            
            .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;
                color: #333;
            }
            
            .nav>li>a:hover {
                background-color: #eee;
            }
            
            .nav ul {
                display: none;
                position: absolute;
                top: 41px;
                left: 0;
                width: 100%;
                border-left: 1px solid #FECC5B;
                border-right: 1px solid #FECC5B;
            }
            
            .nav ul li {
                border-bottom: 1px solid #FECC5B;
            }
            
            .nav ul li a:hover {
                background-color: #FFF5DA;
            }
        style>
    head>
    
    <body>
        <ul class="nav">
            <li>
                <a href="#">微博a>
                <ul>
                    <li>
                        <a href="">私信a>
                    li>
                    <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>
                    <li>
                        <a href="">@我a>
                    li>
                ul>
            li>
            <li>
                <a href="#">微博a>
                <ul>
                    <li>
                        <a href="">私信a>
                    li>
                    <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>
                    <li>
                        <a href="">@我a>
                    li>
                ul>
            li>
        ul>
        <script>
            // 1. 获取元素
            var nav = document.querySelector('.nav');
            var lis = nav.children; // 得到4个小li
            // 2.循环注册事件
            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>
    body>
    
    html>
    

    鼠标指向菜单后出现下拉菜单,离开后自动隐藏:
    【DOM笔记三】节点操作(节点概述、节点层级、添加 / 删除 / 复制节点、DOM基本语法总结!_第3张图片

    5.2.2 兄弟节点
    • node.nextSibling,返回元素下一个兄弟节点(所有类型),找不到返回null
    • node.previousSibling,返回元素上一个兄弟节点(所有类型),找不到返回null
    • node.nextElementSibling,返回元素下一个兄弟元素节点,找不到返回null,IE9以上才支持
    • node.previousElementSibling,返回元素上一个兄弟元素节点,找不到返回null,IE9以上才支持
    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
    head>
    
    <body>
        <div>我是divdiv>
        <span>我是spanspan>
        <script>
            var div = document.querySelector('div');
            // 1.2. nextSibling 下一个兄弟节点,包含:元素节点、文本节点...
            console.log(div.nextSibling);  // #text
            console.log(div.previousSibling);  // #text
            
            // 3.4. nextElementSibling 下一个兄弟元素节点,IE9以上才支持
            console.log(div.nextElementSibling);  // 我是span
            console.log(div.previousElementSibling);   // null
            // 有兼容性问题怎么办?封装一个兼容性函数。
            function getNextElementsibling (element) {
                var el = element;
                while (el = el.nextsibling) {
                    if (el.nodeType === 1) {   // 是元素节点就返回
                        return el;
                    }
                }
                return null;
            }
    
        script>
    body>
    
    html>
    

    5.3 添加元素

    在页面中添加元素的步骤:

    1. 创建节点
    • document.createElement('tagName'),由tagName指定的HTML元素创建。因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点
    1. 添加节点
    • node.appendChild(child);,将一个节点添加到指定父节点的子节点列表末尾,类似于CSS里面的after伪元素。
    • node.insertBefore(child,指定元素);将一个节点添加到指定父节点的指定子节点前面,类似于CSS里面的before伪元素。
    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
    head>
    
    <body>
        <ul>
            <li>123li>
        ul>
        <script>
            // 1. 创建节点元素节点
            var li = document.createElement('li');
            
            // 2. 添加节点node.appendChild(child),类似于数组中的push
            var ul = document.querySelector('ul');
            ul.appendChild(li); // 给ul父节点内的末尾加上小li
            
            // 3. 添加节点node.insertBefore(child, 指定元素);
            var lili = document.createElement('li');
            ul.insertBefore(lili, ul.children[0]);  // ul.children[0]为第一个孩子,在它前面插入lili
        script>
    body>
    
    html>
    

    案例:简单版-发布留言

    需求:输入留言内容,点击发布后内容会出现在下面。

    思路:点击按钮后动态创建一个li,添加到ul里面。
    【DOM笔记三】节点操作(节点概述、节点层级、添加 / 删除 / 复制节点、DOM基本语法总结!_第4张图片

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            
            body {
                padding: 100px;
            }
            
            textarea {
                width: 200px;
                height: 100px;
                border: 1px solid pink;
                outline: none;
                resize: none;
            }
            
            ul {
                margin-top: 50px;
            }
            
            li {
                width: 300px;
                padding: 5px;
                background-color: rgb(245, 209, 243);
                color: red;
                font-size: 14px;
                margin: 15px 0;
            }
        style>
    head>
    
    <body>
        <textarea name="" id="">textarea>
        <button>发布button>
        <ul>
    		
        ul>
        <script>
            // 1. 获取元素
            var btn = document.querySelector('button');
            var text = document.querySelector('textarea');
            var ul = document.querySelector('ul');
            // 2. 注册事件
            btn.onclick = function() {
                if (text.value == '') {   // 用户没输入内容就提交了
                    alert('您没有输入内容');
                    return false;
                } else {
                    // console.log(text.value);  留言的内容
                    // (1) 创建元素
                    var li = document.createElement('li');  // 先有li
                    li.innerHTML = text.value;  // 再进行赋值
                    // (2) 添加元素
                    // ul.appendChild(li);   新写的留言在最后面显示
                    ul.insertBefore(li, ul.children[0]);   // 新写的留言在最前面显示
                }
            }
        script>
    body>
    
    html>
    

    5.4 删除节点

    • node.removeChild(child),删除子节点并返回删除的节点
    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
    head>
    
    <body>
        <button>删除button>
        <ul>
            <li>熊大li>
            <li>熊二li>
            <li>光头强li>
        ul>
        <script>
            // 1.获取元素
            var ul = document.querySelector('ul');
            var btn = document.querySelector('button');
            // 2. 删除元素  node.removeChild(child)
            // ul.removeChild(ul.children[0]);  熊大被删掉
            // 3. 点击按钮依次删除里面第一个孩子
            btn.onclick = function() {
                if (ul.children.length == 0) {
                    this.disabled = true;   // 如果没有元素,按钮就被禁用
                } else {
                    ul.removeChild(ul.children[0]);
                }
            }
        script>
    body>
    
    html>
    

    案例:删除留言

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            
            body {
                padding: 100px;
            }
            
            textarea {
                width: 200px;
                height: 100px;
                border: 1px solid pink;
                outline: none;
                resize: none;
            }
            
            ul {
                margin-top: 50px;
            }
            
            li {
                width: 300px;
                padding: 5px;
                background-color: rgb(245, 209, 243);
                color: red;
                font-size: 14px;
                margin: 15px 0;
            }
            
            li a {
                float: right;
            }
        style>
    head>
    
    <body>
        <textarea name="" id="">textarea>
        <button>发布button>
        <ul>
    
        ul>
        <script>
            // 1. 获取元素
            var btn = document.querySelector('button');
            var text = document.querySelector('textarea');
            var ul = document.querySelector('ul');
            // 2. 注册事件
            btn.onclick = function() {
                if (text.value == '') {
                    alert('您没有输入内容');
                    return false;
                } else {
                    // (1) 创建元素
                    var li = document.createElement('li');
                    li.innerHTML = text.value + "删除";  // 使用javascript:阻止链接跳转,效果比#好
                    
                    // (2) 添加元素
                    ul.insertBefore(li, ul.children[0]);
                    
                    // (3) 删除元素:删除的是当前链接的li(它的父亲)
                    var as = document.querySelectorAll('a');
                    for (var i = 0; i < as.length; i++) {
                        as[i].onclick = function() {  
                            ul.removeChild(this.parentNode);  // node.removeChild(child); 删除的是当前a所在的li,this.parentNode;
                        }
                    }
                }
            }
        script>
    body>
    
    html>
    

    5.5 复制节点

    • node.cloneNode ();,括号为空或者里面是false,为浅拷贝,只复制标签不复制里面的内容
    • node.cloneNode(true);, 括号为true,为深拷贝,复制标签里面的内容
    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
    head>
    
    <body>
        <ul>
            <li>1111li>
            <li>2li>
            <li>3li>
        ul>
        <script>
            var ul = document.querySelector('ul');
            // 1. node.cloneNode(); 浅拷贝
            // 2. node.cloneNode(true); 深拷贝
            var lili = ul.children[0].cloneNode(true);
            ul.appendChild(lili);
        script>
    body>
    
    html>
    

    浅拷贝效果:【DOM笔记三】节点操作(节点概述、节点层级、添加 / 删除 / 复制节点、DOM基本语法总结!_第5张图片 深拷贝效果:

    案例:动态生成表格

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
        <style>
            table {
                width: 500px;
                margin: 100px auto;
                border-collapse: collapse;
                text-align: center;
            }
            
            td,
            th {
                border: 1px solid #333;
            }
            
            thead tr {
                height: 40px;
                background-color: #ccc;
            }
        style>
    head>
    
    <body>
        <table cellspacing="0">
            <thead>
                <tr>
                    <th>姓名th>
                    <th>科目th>
                    <th>成绩th>
                    <th>操作th>
                tr>
            thead>
            <tbody>
             
            tbody>
        table>
        <script>
            // 1.先准备好学生的数据(实际应用:JS动态生成,从数据库中取数据;此处:模拟数据)
            var datas = [{    // 一个数组中放了多个对象
                name: '魏璎珞',
                subject: 'JavaScript',
                score: 100
            }, {
                name: '弘历',
                subject: 'JavaScript',
                score: 98
            }, {
                name: '傅恒',
                subject: 'JavaScript',
                score: 99
            }, {
                name: '明玉',
                subject: 'JavaScript',
                score: 88
            }];
            
            // 2. 往tbody里面创建行:有几个人(看数组的长度)就创建几行
            var tbody = document.querySelector('tbody');
            for (var i = 0; i < datas.length; i++) { // 外面的for循环指行 tr
                var tr = document.createElement('tr');  // 创建tr行
                tbody.appendChild(tr);
                // 行里面创建3个单元格td  for循环遍历对象 datas[i]
                for (var k in datas[i]) {   // 里面的for循环指列 td
                    var td = document.createElement('td');    // 创建单元格 
                    td.innerHTML = datas[i][k];  // 把对象里面的属性值datas[i][k] 给td 
                    tr.appendChild(td);
                }
                // 3. 创建删除列单元格 
                var td = document.createElement('td');
                td.innerHTML = '删除';
                tr.appendChild(td);
            }
            // 4. 删除操作 开始 
            var as = document.querySelectorAll('a');
            for (var i = 0; i < as.length; i++) {
                as[i].onclick = function() {
                    // 点击a,删除当前a所在的行(链接的爸爸的爸爸)  node.removeChild(child)  
                    tbody.removeChild(this.parentNode.parentNode)
                }
            }
        script>
    body>
    
    html>
    

    【DOM笔记三】节点操作(节点概述、节点层级、添加 / 删除 / 复制节点、DOM基本语法总结!_第6张图片

    5.6 三种动态创建元素的区别

    • document.write(),直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
    • element.innerHTML,不会导致页面全部重绘,创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
    • document.createElement(),创建多个元素效率稍低一点点,但是结构更清晰

    总结:不同浏览器下,innerHTML效率要比creatElement高

    6 DOM小结

    1. 创建

      • document.write

      • innerHTML

      • createElement

    2. 增加

      • appendChild

      • insertBefore

    3. 删除

      • removeChild
    4. 修改(元素属性、元素内容、表单的值…)

      • 元素属性:src、href、title等

      • 普通元素内容:innerHTML、innerText

      • 表单元素:value、type、disabled等

      • 元素样式:style、className

    5. 查询(DOM元素)

      • DOM提供的API方法:getElementByld、getElementsByTagName 古老用法不太推荐

      • H5提供的新方法:querySelector、querySelectorAll 提倡

      • 利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling) 提倡

    6. 属性操作(主要针对自定义属性)

      • setAttribute:设置dom的属性值

      • getAttribute:得到dom的属性值

      • removeAttribute:移除属性

    7. 事件操作(给元素注册事件,采取事件源.事件类型=事件处理程序

    【DOM笔记三】节点操作(节点概述、节点层级、添加 / 删除 / 复制节点、DOM基本语法总结!_第7张图片

    你可能感兴趣的:(前端之路,笔记,前端,javascript,学习,DOM)