03-webAPI-节点操作

181 阅读6分钟

1.什么是节点

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

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

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

dom节点树.png

1.DOM节点

1.DOM树里每一个内容都称之为节点

2.节点类型

1.元素节点 所有的标签 比如 body、 div (html 是根节点)

2.属性节点 所有的属性 比如 href

3.文本节点 所有的文本(文本节点包含文字、空格、换行等)

4.其他

2.查找节点

1.父节点查找

1.parentNode 属性

2.返回最近一级的父节点 找不到返回为null

3.语法

子元素.parentNode 
  <body>
    <div>
      <button>目标元素</button>
    </div>
    <script>
      let button = document.querySelector('button');

      // 先获取button 目标元素
      console.dir(button);

      console.dir(button.parentNode); // 获取到父元素  div标签
      // 修改一下父元素的背景颜色
      // console.dir(button.parentNode); // 获取到父元素  div标签
      // button.parentNode.style.backgroundColor = 'red';

      button.parentNode.style.display = 'none';
    </script>
  </body>

2.子节点查找

1.childNodes 获得所有子节点、包括文本节点(空格、换行)、注释节点等

2.children 仅获得所有元素节点 返回的还是一个伪数组

父元素.children
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>11-children.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      ul {
        background-color: aqua;
        padding: 20px;
      }
      li {
        height: 30px;
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <ul>
      <li>a1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
    </ul>
    <ul>
      <li>b1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
    </ul>
    <ul>
      <li>c1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
    </ul>
    <script>
      /* 
      1 获取到所有的ul标签 数组
      2 遍历ul数组 挨个绑定点击事件
      3 点击事件触发了
        1 this = 当前被点击的ul标签 
        2 this.children 获取到 所有的ul的子元素 数组
        3 遍历 children 获取到中的每一个li标签
        4 li.style.display="none"
      
       */
      // let ul=document.querySelector("ul");

      // 获取ul标签下的 子节点
      // console.log(ul.children);

      // console.log(ul.childNodes);// 什么都那

      // 1 获取到所有的ul标签 数组
      let uls = document.querySelectorAll('ul');

      // 遍历ul数组 挨个绑定点击事件
      for (let index = 0; index < uls.length; index++) {
        // 3 点击事件触发了
        uls[index].addEventListener('click', function () {
          // 3.1 3.2 3.3  对被点击的ul的children 做遍历
          for (let j = 0; j < this.children.length; j++) {

            // this.children[j]  表示 每一个li标签
            this.children[j].style.display="none";

          }
        });
      }
    </script>
  </body>
</html>

3.兄弟关系查找

1.nextElementSibling 属性 下一个兄弟节点

2.previousElementSibling 属性 上一个兄弟节点

   <script>
      /* 
     1 获取所有的li标签 数组
     2 遍历 绑定点击事件
     3 事件触发了
       this.next
       this.previou 获取到对应的元素 设置他们的样式
      */

      //  1 获取所有的li标签 数组
      let lis = document.querySelectorAll('li');

      // 2 遍历 绑定点击事件
      for (let index = 0; index < lis.length; index++) {
        // 3 事件触发了
        lis[index].addEventListener('click', function () {
          // 上一个兄弟 设置 蓝色
          this.previousElementSibling.style.backgroundColor = 'blue';
          
          // 下一个兄弟 设置 绿色
          this.nextElementSibling.style.backgroundColor = 'green';
        });
      }
    </script>

3.增加节点

1.创建节点

1.即创造出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点

2.创建元素节点方法:

//创造一个新的元素节点
document.createElement('标签名')

2.追加节点

1.appendChild

 // 插入到父元素的最后一个子元素
父元素.appendChild(要插入的元素)
parent.appendChild(child) //将child的元素添加到parent元素里面去(最后面)

2.insertBofore

//插入到父元素中某个子元素的前面
父元素.insertBefore(要插入的元素,在那个元素前面)
parent.insertBofore(child, refChild)
	//将child元素添加到refChild的前面去
	//如果refChild元素获取不到, 会默认以appendChild形式添加

3.克隆节点

1.cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值

​ 若为true,则代表克隆时会包含后代节点一起克隆

​ 若为false,则代表克隆时不包含后代节点

​ 默认为false

2.语法

//克隆一个已有的元素节点
元素.cloneNode(布尔值)

3.cloneNode() //浅克隆

4.cloneNode(true) //深克隆

<body>
    <div class="box">div
        <button>点击我</button>
    </div>
    <script>
        //1.克隆节点   box这个盒子
        let box = document.querySelector('.box')

        //2.开始克隆
        // let newBox1 = box.cloneNode()  //浅克隆  不会把 div的后代节点一起克隆
        let newBox2 = box.cloneNode(true)  //ture 深克隆  会把div的后代节点一起克隆

        //3  插入到body 标签中
        // document.body.appendChild(newBox1)
        document.body.appendChild(newBox2)
    </script>
</body>

4.删除节点

1.若一个节点在页面中已不需要时,可以删除它

2.在 JavaScript 原生DOM操作中,要删除元素必须通过父元素删除

3.语法

父元素.removeChild(要删除的元素)
//如不存在父子关系则删除不成功
//删除节点和隐藏节点(display:none) 有区别的: 隐藏节点还是存在的,但是删除,则从html中删除节点
父元素.remove()
//删除自己
<body>
    <button>点我</button>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
        <li>9</li>
        <li>10</li>
    </ul>
    <script>
        let button = document.querySelector('button')
        let ul = document.querySelector('ul')

        //要删除的子元素
        // let li =document.querySelector('li:last-child')
        // let li =document.querySelector('li:first-child')
        // let li = document.querySelector('li:nth-child(1)')
        button.addEventListener('click', function () {   //鼠标点击事件
            let li =document.querySelector('li:last-child')
            // 删除指定的元素
            ul.removeChild(li); 

            // 删除自己 
            // ul.remove();
            //button.remove()
        }); 
    </script>

5.时间对象

1.时间对象:用来表示时间的对象

2.作用:可以得到当前系统时间

1.实例化

1.在代码中发现了 new 关键字时,一般将这个操作称为实例化

2.创建一个时间对象并获取时间

3.获得当前时间

let data = new Date()

4.获得指定时间

let date = new Date ('1999-11-11')

2.时间对象方法

因为时间对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式

方法作用说明
getFulllYear()获得年份获取四位年份
getMonth()获得月份取值为0~11
getDate()获得月份中的每一天不同的月份取值也不相同
getDay()获得星期取值为0~6
getHours()获得小时取值为0~23
getMinutes()获得分钟取值为0~59
getSeconds()获得秒取值为0~59

3.获取当前时间案列

  <script>
        let div =document.querySelector('div')
        setInterval (function () {
            let date =new Date()

            let year = date.getFullYear() //年
            let month = date.getMonth() + 1   //月
            let date1 = date.getDate() //号
            let day = date.getDay()   //星期几
            let hours = date.getHours()   //时
            let minutes = date.getMinutes()   //分
            let seconds = date.getSeconds()   //秒
            div.style.fontSize='30px'
            div.innerHTML=`${year}${month}${date1}号<br>星期${day}<br>${hours}${minutes}${seconds}秒`
            
        },1000)
      
    </script>

4.时间戳

1.什么是时间戳

是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式

2.三种方式获取时间戳

1.使用 getTime() 方法

//1.  实例化
let date = new Date()
// 2.  获取时间戳
console.log(dat.getTinme())

2. 简写 +new Date()

 console.log(+(new Date()) );
//只要日期对象   可以使用 +将整个对象 转成 时间戳

3.使用 Date().now()

 console.log(Date.now() );

6.重绘和回流

1.浏览器是如何进行界面渲染的

重绘和回流.png

1.解析(Parser)HTML,生成DOM树(DOM Tree)

2.同时解析(Parser) CSS,生成样式规则 (Style Rules)

3.根据DOM树和样式规则,生成渲染树(Render Tree)

4.进行布局 Layout(回流/重排):根据生成的渲染树,得到节点的几何信息(位置,大小)

5.进行绘制 Painting(重绘): 根据计算和获取的信息进行整个页面的绘制

6.Display: 展示在页面上

2.重绘和回流(重排)

重绘和回流(重排).png

重绘不一定引起回流,而回流一定会引起重绘。

1.回流(重排)

当 Render Tree 中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过 程称为 回流。

2.重绘

由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、 outline等), 称为重绘。

3.会导致回流(重排)的操作:

1.页面的首次刷新

2.浏览器的窗口大小发生改变

3.元素的大小或位置发生改变

4.改变字体的大小

5.内容的变化(如:input框的输入,图片的大小)

6.激活css伪类 (如::hover)

7.脚本操作DOM(添加或者删除可见的DOM元素)

8.简单理解影响到布局了,就会有回流

7.综合案列

1.来回传菜

1.方法一

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        ul {
            list-style: none;
            width: 400px;
            height: 400px;
        }
        li {
            width: 400px;
            height: 100px;
            background-color: skyblue;
        }  
        .left{
            float: left;
            background-color: pink;
        }
        .right{
            float: right; 
            background-color: red;
        }
    </style>
</head>
<body>
    <ul class="left">
        <li>龙虾</li>
        <li>鲍鱼</li>
        <li>帝皇蟹</li>
        <li>鱼子酱</li>
    </ul>
    <ul class="right">

    </ul>
    <script>
        let left = document.querySelectorAll('li')
        let right = document.querySelector('.right')
        console.log(left);
        console.log(right);
        for (let index = 0; index < left.length; index++) {
            left[index].addEventListener('click',function () {
                console.log();
                right.appendChild(left[index])
            })          
        }
        for (let index = 0; index < left.length; index++) {
            left[index].addEventListener('click',function () {
                console.log();
                left.appendChild(left[index])
            })          
        }
    </script>
</body>
</html>

2.方法二

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>14-剪切-移动.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      body {
        display: flex;
        justify-content: space-between;
        padding: 100px;
      }
      ul {
        width: 300px;
      }
      .left {
        background-color: yellow;
      }
      .right {
        background-color: blueviolet;
      }
    </style>
  </head>
  <body>
    <ul class="left">
      <li>龙虾</li>
      <li>鲍鱼</li>
      <li>皇帝蟹</li>
      <li>鱼子酱</li>
    </ul>
    <ul class="right"></ul>

    <script>
      /* 
      问题
      1 移动的方向不确定  
        在判断 点击时候  先判断 哪个ul标签的子元素的长度为 0  就移动到谁哪里
       */

      let lis = document.querySelectorAll('li');

      let left = document.querySelector('.left');
      let right = document.querySelector('.right');

      // 准备要插入新元素的  父元素
      let parent;

      for (let index = 0; index < lis.length; index++) {
        lis[index].addEventListener('click', function () {
          // 先判断当前要插入到哪个标签中 谁的子元素长度为0 就插入到谁哪里
          // right.appendChild(this);
          if (right.children.length === 0) {
            // 现在要插入到右边
            parent = right;
          }
          if (left.children.length === 0) {
            parent = left;
          }

          parent.appendChild(this);
        });
      }
    </script>
  </body>
</html>

3.方法三

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>14-剪切-移动.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      body {
        display: flex;
        justify-content: space-between;
        padding: 100px;
      }
      ul {
        width: 300px;
      }
      .left {
        background-color: yellow;
      }
      .right {
        background-color: blueviolet;
      }
    </style>
  </head>
  <body>
    <ul class="left">
      <li>龙虾</li>
      <li>鲍鱼</li>
      <li>皇帝蟹</li>
      <li>鱼子酱</li>
    </ul>
    <ul class="right"></ul>

    <script>
      /* 
       要插入到哪里 不确定

       1 获取被点击的元素的父元素
         left > 皇帝蟹  this.parentNode 
       2 父元素之后 和 left 或者 right比较
        如果 被点击的父元素  不等于 right ,设置 要插入的父元素 = right 
        如果 被点击的父元素  不等于 left ,设置 要插入的父元素 = left 
      
       */

      let lis = document.querySelectorAll('li');
      let left = document.querySelector('.left');
      let right = document.querySelector('.right');

      let parent;

      for (let index = 0; index < lis.length; index++) {
        lis[index].addEventListener('click', function () {
          // if (this.parentNode !== right) {
          //   parent = right;
          // }
          // if (this.parentNode !== left) {
          //   parent = left;
          // }

          parent = this.parentNode !== right ? right : left;

          parent.appendChild(this);
        });
      }
    </script>
  </body>
</html>

2.页面渲染案列

QQ截图20220416121723.png

素材

course01.png

let data = [
  {
    src: 'images/course01.png',
    title: 'Think PHP 5.0 博客系统实战项目演练111',
    num: 1125
  },
  {
    src: 'images/course02.png',
    title: 'Android 网络动态图片加载实战',
    num: 357
  },
  {
    src: 'images/course03.png',
    title: 'Angular2 大前端商城实战项目演练',
    num: 22250
  },
  {
    src: 'images/course04.png',
    title: 'Android APP 实战项目演练',
    num: 389
  },
  {
    src: 'images/course05.png',
    title: 'UGUI 源码深度分析案例',
    num: 124
  },
  {
    src: 'images/course06.png',
    title: 'Kami2首页界面切换效果实战演练',
    num: 432
  },
  {
    src: 'images/course07.png',
    title: 'UNITY 从入门到精通实战案例',
    num: 888
  },
  {
    src: 'images/course08.png',
    title: 'Cocos 深度学习你不会错过的实战',
    num: 590
  },
  {
    src: 'images/course08.png',
    title: '从入门到精通',
    num: 5901
  }
]

1.方法一

<!-- 
  1 引入style.css
  2 引入 data.js
  3 根据data.js中的data数组 来遍历生成代码 
    最终让网页显示出来 data数组的数据
 -->
 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Document</title>
     <link rel="stylesheet" href="./style.css">
     <style>
         *{
             margin: 0;
             padding: 0;
             box-sizing: border-box;
         }
     </style>
 </head>
 <body>
     <script src="./data/data.js"></script>
     <script>
      //  头部
       let html = `
       <div class="box w">
  <div class="box-hd">
    <h3>精品推荐</h3>
    <a href="#">查看全部</a>
  </div>
  <div class="box-bd">
    <ul class="clearfix">
       `
          //中间部分
      for (let index = 0; index < 10; index++) {
        html+=`
        <li>
        <img src="images/course01.png" alt="" />
        <h4>
          Think PHP 5.0 博客系统实战项目演练
        </h4>
        <div class="info">
          <span>高级</span><span>1125</span>人在学习
        </div>
      </li> 
      `
      }
       //尾部

       html+=   `
        </ul>
  </div>
</div>`

document.write(html)
     </script>
 </body>
 </html>

2.方法二

<!-- 
  1 引入style.css
  2 引入 data.js
  3 根据data.js中的data数组 来遍历生成代码 
    最终让网页显示出来 data数组的数据
 -->
 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Document</title>
     <link rel="stylesheet" href="./style.css">
     <style>
         *{
             margin: 0;
             padding: 0;
             box-sizing: border-box;
         }
     </style>
 </head>
 <body>
    <div class="box w">
        <div class="box-hd">
          <h3>精品推荐</h3>
          <a href="#">查看全部</a>
        </div>
        <div class="box-bd">
          <ul class="clearfix list"></ul>
        </div>
      </div>
        <!-- 1 引入 要显示的数据 -->
     <script src="./data/data.js"></script>
       <!-- 2 在写自己的业务 -->
     <script>
      /* 
     1 获取到要渲染到页面中的数据  data 
     2 遍历data
      要求使用 createElement appendChild 来往ul中插入 li 元素 
      1 创建一个li标签
      2 创建一个图片便签 设置 src属性
      3 创建一个h4标签 设置文本内容
      4 创建一个div标签 添加一个class info
      5 创建两个span标签
        1个设置内容 高级 
        2个设置人数 1125 

      6 组装
        li标签要 插入 img
        li标签要 插入 h4
        li标签要 插入 div.info
        div.info 要插入两个span 
        ul插入 li 
    3 append可以插入多个元素  appendChild  只能插入一个元素 
      createTextNode 创建文件节点     
      */
     let ul =document.querySelector('.list')  //获取ul标签

     for (let index = 0; index < data.length; index++) { //遍历 data 数组
        //创建li 标签
        let li =document.createElement('li')
        //创建img 图片标签
        let img = document.createElement('img')
        img.src = data[index].src
        //创建h4标签
        let h4 =document.createElement('h4')
        h4.innerText = data[index].title
        //创建div标签
        let div =document.createElement('div')
        div.classList.add('info') //div添加info 类名

        let text1 = document.createTextNode(' • ');
        let text2 = document.createTextNode('人在学习');

        //创建span标签
        let span1 =document.createElement('span')  
        span1.innerText = '高级' //span1的文字       
        let span2 =document.createElement('span')
        span2.innerText = data[index].num  //span2的文字
        console.log(div[0]);
   
        //将img h4 div 插入li标签对应的位置
        div.append(span1, text1, span2, text2);
        li.append(img, h4, div);
        //将li标签 插入ul标签
        ul.appendChild(li);

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