DOM基础(节点)

1.节点介绍

为什么引入节点?

  • 利用DOM提供的多种获取方法
    • 缺点:繁琐+逻辑性不强
    • 需要重复获取元素
  • 利用节点获取元素
    • 利用父子兄弟节点关系获取元素
    • 缺点:兼容性差

2. 节点概述

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

  • 所有内容是节点(用node表示)
  • 元素也是节点:元素节点
  • 文档节点
  • 属性节点
  • 文本节点(包括空格)
  • 实际操作中主要获取元素节点(然后就可以引出兄弟父子节点)

3. 节点类型判断

node.nodeType

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

4. 父级节点

node.parentNode

5. 子级节点

  1.  获取到元素节点+文本节点方式

  • 以伪数组形式获得元素节点

parentNode.childNodes    标准子节点获取方式

 parentNode.childNodes[index]   获取指定下标子节点

       2.获得元素子节点方式     

  • 以伪数组形式获得元素节点

parentNode.children    非标准子节点获取方式

  • 直接获取指定元素节点 (适合开发使用) 

  • ol.children[0]
  • ol.children[ol.children.length - 1]
  • 也许会获得文本元素

  • parentNode.firstchild
  • parentNode.lastchild
  • 查找子节点元素

parentNode.firstElementchild   注意受兼容ie9

6. 案例-下拉菜单(使用子节点操作) 

  <script>
      // 1.获取元素
      var nav = document.querySelector(".nav");
      var lis = nav.children; //获取四个小li
      //   根据循环注册事件
      for (var i = 0; i < lis.length; i++) {
        lis[i].onmouseover = function () {
          // li里面的第一个元素ul(包裹其他元素)就是第一个元素节点显示出来
          this.children[1].style.display = "block";
        };
        lis[i].onmouseout = function () {
          this.children[1].style.display = "none";
        };
      }
    </script>
  1. 执行效果:鼠标移动到哪个ul上就会显示当前的ul,但是如果从当前ul移除就会消失

  2. 代码解析:

  • 布置静态页面 
  • 首先获取到元素大盒子+大盒子下的多个小盒子
  • 遍历小盒子
  • 当前小盒子设置鼠标移动事件
    • 移动上去:当前小盒子(不包括a链接)的元素显示
    • 移动出去:当前小盒子(不包括a链接)的元素隐藏

7. 兄弟节点

  • node.nextSibling                    下一个兄弟节点
  • node.previousSibling            上一个兄弟节点
  • 缺点:容易获取到文本元素节点(介绍点属性3)

直接封装一个兄弟元素节点获取方式

 function getNextElementSibling(element) {
        var el = element;
        while ((el = el.nextSibling)) {
          if (el.nodeType === 1) {
            return el;
          }
        }
        return null;
      }

  • node.nextElementSibling          下一个兄弟元素节点
  • node.previousElementSibling          上一个兄弟元素节点
  • 如果没有找到兄弟元素节点则返回null

8. 创建节点+添加节点

  1. 相对于整个文档创建节点: document.createElement('tagName')
  2. 添加到指定父节点下的位置
    1. 父node.appendChild(child)    添加到指定父节点后面
    2. 父node.insertBefore(child,指定节点)      添加子节点到指定父节点的子节点前面

  <body>
    <ul>
      <li>123</li>
    </ul>
    <script>
      // 1.在整个文档页面创建节点:元素节点
      var li = document.createElement("li");
      //   2.把节点放到父节点最后面
      var ul = document.querySelector("ul");
      ul.appendChild(li); //追加元素  类似于push
      //   3.把创建节点放在父节点指定元素前面
      //   创建节点
      var lili = document.createElement("li");
      ul.insertBefore(lili, ul.children[0]);
      //4.想要添加一个新的元素:创建元素+添加元素
    </script>
  </body>

9. 案例-发布评论

 <body>
    <div class="box">
      <textarea name="" id="" cols="30" rows="10"></textarea>
      <button>发布</button>
      <ul></ul>
    </div>
    <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才能赋值
          li.innerHTML = text.value;
          // 2.添加得ul
          ul.insertBefore(li, ul.children[0]);
        }
      };
    </script>
  </body>

  1. 执行效果:文本内容中输入内容点击发布就会出现下方创建并添加节点

  2. 代码解析:

  •  布置静态页面
  • 获取元素
  • 按钮设置点击事件
  • 判断
    • 如果当前文本框没有内容则弹窗:没有输入文字
    • 否则创建节点
      • 创建好节点
      • 修改当前节点内容
      • 并把当前节点添加到ul的最前面

10. 删除节点

  • 父node.removeChild(child)
  • 删除父节点的第几个子节点
   <body>
    <button>删除</button>
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </ul>
    <script>
      // 1. 获取元素
      var ul = document.querySelector("ul");
      var btn = document.querySelector("button");
      //   2.删除节点:删除父节点的第几个节点
      //   ul.removeChild(ul.children[0]);
      //   3.点击按钮以此删除
      btn.onclick = function () {
        if (ul.children.length == 0) {
          btn.disabled = true; //禁用按钮属性
        } else {
          ul.removeChild(ul.children[0]);
        }
      };
    </script>

11.案例-删除节点 

<body>
    <div class="box">
      <textarea name="" id="" cols="30" rows="10"></textarea>
      <button>发布</button>
      <ul></ul>
    </div>
    <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才能赋值+删除链接
          // 注意a的链接地址更换之后才不会跳转出现乱七八糟的
          li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
          // 2.添加得ul
          ul.insertBefore(li, ul.children[0]);
          //3.删除事件
          var as = document.querySelectorAll("a");
          for (var i = 0; i < as.length; i++) {
            as[i].onclick = function () {
              //删除事件(删除a节点的父节点li)
              ul.removeChild(this.parentNode);
            };
          }
        }
      };
    </script>
  </body>
  1. 实现效果:在添加节点的基础上并添加一个删除链接(点击删除就会删除父节点)

  2. 代码解析

  •  布置静态页面
  • 获取元素
  • 设置按钮点击事件
  • 判断
    • 如果当前文本框没有内容则弹窗:没有输入文字
    • 否则创建节点li
      • 创建好节点
      • 修改当前节点内容+标签a标签包括删除内容
      • 并把当前节点添加到ul的最前面
      • 设置删除事件
      • 获取所有a元素
      • 遍历a并给当前a标签设置点击事件
      • 父元素删除当前子节点的父节点

 12.克隆节点

node.clonNode()

  1. 如果参数为空或为false,则是浅拷贝,,即克隆隆赋值节点本身,不克隆里面子节点(内容。)

  2. 如果参数为true:代表克隆或者赋值里面所有内容(深拷贝)

 <body>
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </ul>
    <script>
      var ul = document.querySelector("ul");
      //   1.克隆
      //   node.colonNode():参数为空或者false,就是浅拷贝,只复制标签不赋值内容
      //   如果里面是true就是深拷贝:赋值或者克隆所有内容
      var cl_ul = ul.children[0].cloneNode(true);
      //   2.插入节点
      ul.appendChild(cl_ul);
    </script>
  </body>

13. 案例-动态生成表格 

   <script>
      // 1.先准备数据
      var dates = [
        {
          name: "刘某",
          subject: "JacaScrit",
          score: 100,
        },
        {
          name: "任某",
          subject: "JacaScrit",
          score: 90,
        },
        {
          name: "张某",
          subject: "JacaScrit",
          score: 80,
        },
        {
          name: "屠某",
          subject: "JacaScrit",
          score: 70,
        },
        {
          name: "张某",
          subject: "JacaScrit",
          score: 70,
        },
      ];
      // 2.往tbody创建行:通过数组长度
      var tbody = document.querySelector("tbody");
      for (var i = 0; i < dates.length; i++) {
        // 创建行
        var tr = document.createElement("tr");
        // 插入
        tbody.appendChild(tr);
        // 创建td:数值取决于对象个数
        for (var k in dates[i]) {
          // k得到属性名
          // obj[k]:得到属性值
          var td = document.createElement("td");
          // 创建td的同时把属性值给td
          td.innerHTML = dates[i][k];
          // 插入
          tr.appendChild(td);
        }
        // 重新创建删除单元格
        var td = document.createElement("td");
        td.innerHTML = "<a href='javascript:;'>删除</a>";
        tr.appendChild(td);
      }
      //4.删除操作
      var as = document.querySelectorAll("a");
      for (var i = 0; i < as.length; i++) {
        as[i].onclick = function () {
          // 点击a删除所在行:node.removeChild(child)
          //a是td的孩子,td又是tr的孩子
          tbody.removeChild(this.parentNode.parentNode);
        };
      }
    </script>
  1. 执行效果:根据程序对象添加多个表格行并可以点击删除当前一行

  2. 代码解析

  • 布置静态页面(只有当前页面的表头)给一个空的表格内容
  • 创建一个对象:所有类都设置好
  • 获取元素tbody
  • 遍历对象
    • 根据对象数:创建行并插入到tbody的后面
    • 遍历当前对象
      • 创建td并添加对象内容给当前元素节点
      • 把创建的节点插入到行的最后面
  • 单独创建一个单元格
    • 把删除链接添加给单元格
    • 并把单元格添加到行的最后面
  • 删除操作
    • 获取所有标签a
    • 遍历所有标签a
    • 设置当前标签a点击事件
    • 父节点删除当前子节点的父节点的父节点

14. 三种创建元素节点

  • document.write(’标签+元素内容‘)

  • 缺点:页面重置,原先创建的元素就会消失

      var btn = document.querySelector("button");
      btn.onclick = function () {
        // 会重新创建页面:原先的页面就没了
        document.write("<div>123</div>");
      };

  • element.innerHTML = ’标签+元素内容‘
      var inner = document.querySelector(".inner");
      // 拼接字符串 效率比较慢
      for (var i = 0; i <= 100; i++) {
        inner.innerHTML += '<a href="#">百度</a>';
      }

  • document.creatElement('节点')
  • 注意需要添加到父元素指定位置
      var creat = document.querySelector(".creat");

      for (var i = 0; i <= 100; i++) {
        var a = document.createElement("a");
        creat.appendChild(a);
      }

15. 比较创建节点最优性

  • 最优创建节点:测试获取两个不同时间戳并进行计算添加后的时间差
  • 测试:根据push到数组并转成字符串join 
 <script>
    function fn() {
      var dl = +new Date();
      // 初始化空数组
      var array = [];
      // 依次在数组后面push一个元素(带有样式)
      for (var i = 0; i < 1000; i++) {
        array.push(
          '<div style="width: 100px;height: 2px;border: 1px solid #000;"></div>'
        );
      }
      // 数组转化成字符串
      document.body.innerHTML = array.join("");
      var d2 = +new Date();
      console.log(d2 - dl);
    }
    fn();
  </script>

  • 较快创建节点: 
  • 测试:
  • 遍历:直接创建节点并直接添加属性最后添加节点到父级节点
  <script>
    function fn() {
      // 获取未执行前时间
      var d1 = +new Date();
      for (var i = 0; i < 1000; i++) {
        // 利用creatElement创建元素并且添加好样式
        var div = document.createElement("div");
        div.style.width = "100px";
        div.style.height = "2px";
        div.style.border = "1px solid red";
        // 依次添加到body里面
        document.body.appendChild(div);
      }
      // 获取执行后时间
      var d2 = +new Date();
      console.log(d2 - d1);
    }
    fn();
  </script>

  • 最慢节点创建 
  • 测试:直接使用innerHTML创建一个带有属性的节点
    <script>
        function fn() {
          // 获得当前时间
          var d1 = +new Date();
    
          var str = "";
          for (var i = 0; i < 1000; i++) {
            // 利用html创建元素并且添加好样式
            document.body.innerHTML +=
              '<div style="width: 100px;height: 2px;border: 1px solid #000;"></div>';
          }
          // 运行之后的当前时间
          var d2 = +new Date();
          console.log(d2 - d1);
        }
        fn();
      </script>

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值