节点操作

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>

 

posted @ 2020-09-21 15:17  星辰ꦿ.大海  阅读(219)  评论(0编辑  收藏  举报