zoukankan      html  css  js  c++  java
  • 节点操作

    1.1. 节点概述

    为什么学节点操作

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

    HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。

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

    1.2. 节点层级

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

    1.3. 父级节点

        <div class="demo">
           <div class="box">
               <span class="erweima">×</span>
           </div>
       </div>
       <script>
           // 1. 父节点 parentNode
           var erweima = document.querySelector('.erweima');
           // var box = document.querySelector('.box');
           // 得到的是离元素最近的父级节点(亲爸爸) 如果找不到父节点就返回为 null
           console.log(erweima.parentNode);
       </script>

    1.4. 子节点

    所有子节点

    子元素节点

        <ul>
           <li>我是li</li>
           <li>我是li</li>
           <li>我是li</li>
           <li>我是li</li>
       </ul>
       <script>
           // DOM 提供的方法(API)获取
           var ul = document.querySelector('ul');
           var lis = ul.querySelectorAll('li');
           // 1. 子节点 childNodes 所有的子节点 包含 元素节点 文本节点等等
           console.log(ul.childNodes);
           console.log(ul.childNodes[0].nodeType);
           console.log(ul.childNodes[1].nodeType);
           // 2. children 获取所有的子元素节点 也是我们实际开发常用的
           console.log(ul.children);
       </script>

    第1个子节点

    最后1个子节点

    第1个子元素节点

    最后1个子元素节点

    实际开发中,firstChild 和 lastChild 包含其他节点,操作不方便,而 firstElementChild 和 lastElementChild 又有兼容性问题,那么我们如何获取第一个子元素节点或最后一个子元素节点呢?

        <ol>
           <li>我是li1</li>
           <li>我是li2</li>
           <li>我是li3</li>
           <li>我是li4</li>
           <li>我是li5</li>
       </ol>
       <script>
           var ol = document.querySelector('ol');
           // 1. firstChild 第一个子节点 不管是文本节点还是元素节点
           console.log(ol.firstChild);
           console.log(ol.lastChild);
           // 2. firstElementChild 返回第一个子元素节点 ie9才支持
           console.log(ol.firstElementChild);
           console.log(ol.lastElementChild);
           // 3. 实际开发的写法 既没有兼容性问题又返回第一个子元素
           console.log(ol.children[0]);
           console.log(ol.children[ol.children.length - 1]);//最后一个子元素
       </script>

    1.5. 案例:新浪下拉菜单

     

     实现代码

        <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>

    1.6. 兄弟节点

        <div>我是div</div>
       <span>我是span</span>
       <script>
           var div = document.querySelector('div');
           // 1.nextSibling 下一个兄弟节点 包含元素节点或者 文本节点等等
           console.log(div.nextSibling);
           console.log(div.previousSibling);
           // 2. nextElementSibling 得到下一个兄弟元素节点
           console.log(div.nextElementSibling);
           console.log(div.previousElementSibling);
       </script>

    如何解决兼容性问题?封装一个兼容性函数解决

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

    1.7. 创建节点

    1.8. 添加节点

        <ul>
           <li>123</li>
       </ul>
       <script>
           // 1. 创建节点元素节点
           var li = document.createElement('li');
           // 2. 添加节点 node.appendChild(child) node 父级 child 是子级 后面追加元素,类似于数组中的push
           var ul = document.querySelector('ul');
           ul.appendChild(li);
           // 3. 添加节点 node.insertBefore(child, 指定元素);
           var lili = document.createElement('li');
           ul.insertBefore(lili, ul.children[0]);
           // 4. 我们想要页面添加一个新的元素 : 1. 创建元素 2. 添加元素
       </script>

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

     

    <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>

     

    1.10 删除节点

    node.removeChild(child)

    node.removeChild() 方法从 node节点中删除一个子节点,返回删除的节点。

        <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>

     

    1.11 案例:删除留言

        <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 + "<a href='javascript:;'>删除</a>";
                   // (2) 添加元素
                   // ul.appendChild(li);
                   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() {
                           // 删除的是 li 当前a所在的li this.parentNode;
                           ul.removeChild(this.parentNode);
                      }
                  }
              }
          }
       </script>

    1.12 复制(克隆)节点

        <ul>
           <li>1111</li>
           <li>2</li>
           <li>3</li>
       </ul>
       <script>
           var ul = document.querySelector('ul');
           // 1. node.cloneNode(); 括号为空或者里面是false 浅拷贝 只复制标签不复制里面的内容
           // 2. node.cloneNode(true); 括号为true 深拷贝 复制标签复制里面的内容
           var lili = ul.children[0].cloneNode(true);
           ul.appendChild(lili);
       </script>

    1.13 案例:动态生成表格

     

        <script>
           // 1.先去准备好学生的数据
           var datas = [{
               name: '魏璎珞',
               subject: 'JavaScript',
               score: 100
          }, {
               name: '弘历',
               subject: 'JavaScript',
               score: 98
          }, {
               name: '傅恒',
               subject: 'JavaScript',
               score: 99
          }, {
               name: '明玉',
               subject: 'JavaScript',
               score: 88
          }, {
               name: '大猪蹄子',
               subject: 'JavaScript',
               score: 0
          }];
           // 2. 往tbody 里面创建行: 有几个人(通过数组的长度)我们就创建几行
           var tbody = document.querySelector('tbody');
    // 遍历数组
           for (var i = 0; i < datas.length; i++) {
               // 1. 创建 tr行
               var tr = document.createElement('tr');
               tbody.appendChild(tr);
               // 2. 行里面创建单元格td 单元格的数量取决于每个对象里面的属性个数  
               // 使用for in遍历学生对象
               for (var k in datas[i]) {
                   // 创建单元格
                   var td = document.createElement('td');
                   // 把对象里面的属性值 datas[i][k] 给 td  
                   td.innerHTML = datas[i][k];
                   tr.appendChild(td);
              }
               // 3. 创建有删除2个字的单元格
               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 删除 当前a 所在的行(链接的爸爸的爸爸) node.removeChild(child)  
                   tbody.removeChild(this.parentNode.parentNode)
              }
          }
       </script>

     

    星辰ꦿ.大海
  • 相关阅读:
    对QR码的初步研究(附:在博客里放上博客文章的QR码)
    EonerCMS——做一个仿桌面系统的CMS(十四)
    终于病了
    【HoorayOS】开源的Web桌面应用框架(第二版 v120311)
    【HoorayOS】开源的Web桌面应用框架——EonerCMS更名为HoorayOS
    一句代码实现 HTML5 语音搜索
    HTML5 拖拽上传图片实例
    【HoorayOS】开源的Web桌面应用框架
    【HoorayOS】开源的Web桌面应用框架(文件夹功能分析)
    从源码分析常见的基于Array的数据结构动态扩容机制
  • 原文地址:https://www.cnblogs.com/xc-dh/p/13705763.html
Copyright © 2011-2022 走看看