JavaScript自学Day9-DOM节点

143 阅读4分钟

日期:2023-04-13 学习目标:进一步学习 DOM 相关知识,实现可交互的网页特效;能够插入、删除和替换元素节点;能够依据元素节点关系查找节点

1. 日期对象

掌握 Date 日期对象的使用,动态获取当前计算机的时间。

ECMAScript 中内置了获取系统时间的对象 Date,使用 Date 时与之前学习的内置对象 console 和 Math 不同,它需要借助 new 关键字才能使用。

1.1 实例化和日期对象方法

//1.实例化  在代码中发现了 new 关键字时,一般将这个操作称为实例化
//1.1得到当前时间
const date = new Date();
console.log(date);
//1.2得到指定时间
const date1 = new Date('2022-5-1');
console.log(date1);

//2.日期对象方法
//2.1.getFullYear() 获得年 四位数
console.log(date.getFullYear()); 
//2.2.getMonth() 获得月 范围:0~11
console.log(date.getMonth()+1);
//2.3.getDate() 获得日 月不同取值不同
console.log(date.getDate());
//2.4.getDay() 获得星期 范围0~6 '0'表示周日
console.log(date.getDay());

getFullYear 获取四位年份 getMonth 获取月份,取值为 0 ~ 11 getDate 获取月份中的每一天,不同月份取值也不相同 getDay 获取星期,取值为 0 ~ 6 '0'代表周日 getHours 获取小时,取值为 0 ~ 23 getMinutes 获取分钟,取值为 0 ~ 59 getSeconds 获取秒,取值为 0 ~ 59

// 根据获得星期getDay()方法 返回的是 星期一~星期日
const arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
//getDay()方法 取值0~6 作为数组索引号
console.log(arr[new Date().getDay()])

1.2 电子时钟案例

const div = document.querySelector('.time')
//格式化显示时间
function getMyDate() {
    //实例化
    const date = new Date()
    //补零
    let h = date.getHours()
    let m = date.getMinutes()
    let s = date.getSeconds()
    h = h < 10 ? '0' + h : h
    m = m < 10 ? '0' + m : m
    s = s < 10 ? '0' + s : s
    //返回格式化时间
    return `${date.getFullYear()}${date.getMonth() + 1}${date.getDate()}${h}:${m}:${s}`
}
div.innerHTML = getMyDate()
//间歇函数 开启定时器
setInterval(function(){
    div.innerHTML = getMyDate()
},1000)

另一种格式化时间的写法:

const div = document.querySelector('.time')
//实例化
const date = new Date()
//toLocaleString() 返回一个字符串表示数组中的元素
div.innerHTML = date.toLocaleString()     // 2023/4/13 11:01:40
//toLocaleDateString() 返回该日期对象日期部分的字符串
div.innerHTML = date.toLocaleDateString() // 2023/4/13
//toLocaleTimeString() 返回该日期对象时间部分的字符串
div.innerHTML = date.toLocaleTimeString() // 11:02:55

1.3 时间戳

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

注:ECMAScript 中时间戳是以毫秒计的。

获取时间戳的方法:

  // 1. getTime()方法 必须先实例化,再使用该方法
  const date = new Date()
  console.log(date.getTime())
  // 2.+new Date()方法
  console.log(+new Date())
  // Date.now()方法
  console.log(Date.now())

注意:Date.now()方法只能获得当前时间的时间戳,getTime()+new Date()可以返回指定时间的时间戳

1.4 倒计时案例

天/时/分/秒转换公式 d = parseInt(总秒数/ 60/60 /24); 计算天数 h = parseInt(总秒数/ 60/60 %24) 计算小时 m = parseInt(总秒数 /60 %60 ); 计算分数 s = parseInt(总秒数%60); 计算秒数

<!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>
        .countdown {
            width: 240px;
            height: 305px;
            text-align: center;
            line-height: 1;
            color: #fff;
            background-color: brown;
            /* background-size: 240px; */
            /* float: left; */
            overflow: hidden;
        }

        .countdown .next {
            font-size: 16px;
            margin: 25px 0 14px;
        }

        .countdown .title {
            font-size: 33px;
        }

        .countdown .tips {
            margin-top: 50px;
            font-size: 22px;
            line-height: 1.2;
        }

        .countdown small {
            font-size: 17px;
        }

        .countdown .clock {
            width: 142px;
            margin: 18px auto 0;
            overflow: hidden;
        }

        .countdown .clock span,
        .countdown .clock i {
            display: block;
            text-align: center;
            line-height: 34px;
            font-size: 23px;
            float: left;
        }

        .countdown .clock span {
            width: 34px;
            height: 34px;
            border-radius: 2px;
            background-color: #303430;
        }

        .countdown .clock i {
            width: 20px;
            font-style: normal;
        }
    </style>
</head>

<body>
    <div class="countdown">
        <p class="next">今天是2023年4月13日</p>
        <p class="title">距今天结束还有</p>
        <p class="clock">
            <span id="hour">00</span>
            <i>:</i>
            <span id="minutes">25</span>
            <i>:</i>
            <span id="scond">20</span>
        </p>
        <p class="tips">路漫漫其修远兮<br>吾将上下而求索</p>
    </div>
    <script>
        //1.获取元素
        const next = document.querySelector('.next')
        const hour = document.querySelector('#hour')
        const minutes = document.querySelector('#minutes')
        const scond = document.querySelector('#scond')
        //2.封住time函数
        function getTime() {
            //2.1用未来时间戳 - 当前时间戳 得到毫秒数/1000 获得秒数
            const time = (+new Date('2023-4-14') - +new Date()) / 1000
            //2.2求时分秒,补零
            let h = parseInt(time / 60 / 60 % 24)
            h = h < 10 ? '0' + h : h
            let m = parseInt(time / 60 % 60)
            m = m < 10 ? '0' + m : m
            let s = parseInt(time % 60)
            s = s < 10 ? '0' + s : s
            //2.3将时分秒显示到页面中
            hour.innerHTML = `${h}`
            minutes.innerHTML = `${m}`
            scond.innerHTML = `${s}`
        }
        //3.先调用一次,显示到页面上
        getTime()
        //4.开启定时器
        setInterval(getTime, 1000)
    </script>
</body>
</html>

2. DOM 节点

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

节点类型

  • 元素节点:所有的标签 比如 body、div,html是根节点
  • 属性节点:所有的属性 比如 href
  • 文本节点:所有的文本
  • 其它

2.1 查找节点

DOM 树中的任意节点都不是孤立存在的,它们要么是父子关系,要么是兄弟关系,不仅如此,我们可以依据节点之间的关系查找节点。

父子关系

通过parentNode属性,查找父节点:(重点)

子元素.parentNode

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

通过childNodes属性,查找所有子节点

父元素.childNodes

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

通过children 属性,查找所有元素子节点:(重点)

父元素.children

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

例1:关闭广告

<body>
  <div class="box">
    这是一条广告
    <div class="close">X</div>
  </div>
  <div class="box">
    这是一条广告
    <div class="close">X</div>
  </div>
  <div class="box">
    这是一条广告
    <div class="close">X</div>
  </div>
  <script>
    //1.获取三个关闭按钮
    const closeBtn = document.querySelectorAll('.close')
    //2.给三个关闭按钮绑定点击事件
    for (let i = 0; i < closeBtn.length; i++) {
      closeBtn[i].addEventListener('click', function () {
        //隐藏父节点元素
        this.parentNode.style.display = 'none'
      })
    }
  </script>
</body>

结论:parentNode 获取父节点,以相对位置查找节点,实际应用中非常灵活。

例2:

<body>
  <button class="btn1">所有的子节点</button>
  <!-- 获取 ul 的子节点 -->
  <ul>
    <li>HTML</li>
    <li>CSS</li>
    <li>JavaScript 基础</li>
    <li>Web APIs</li>
  </ul>
  <script>
    const btn1 = document.querySelector('.btn1')
    btn1.addEventListener('click', function () {
      // 父节点
      const ul = document.querySelector('ul')

      // 所有的子节点
      console.log(ul.childNodes)
      // 只包含元素子节点
      console.log(ul.children)
    })
  </script>
</body>

结论:

  • childNodes 获取全部的子节点,回车换行会被认为是空白文本节点
  • children 只获取元素类型节点

兄弟关系

previousSibling 获取前一个兄弟节点,以相对位置查找节点,实际应用中非常灵活。 nextSibling 获取后一个兄弟节点,以相对位置查找节点,实际应用中非常灵活。

<body>
  <ul>
    <li>HTML</li>
    <li>CSS</li>
    <li>JavaScript 基础</li>
    <li>Web APIs</li>
  </ul>
  <script>
    // 获取所有 li 节点
    const lis = document.querySelectorAll('ul li')

    // 对所有的 li 节点添加事件监听
    for(let i = 0; i < lis.length; i++) {
      lis[i].addEventListener('click', function () {
        // 前一个节点
        console.log(this.previousSibling)
        // 下一下节点
        console.log(this.nextSibling)
      })
    }
  </script>
</body>

2.2 增加/插入节点

增加节点的步骤

  1. 创建节点:创建一个新的节点,即创造出一个新的网页元素,再添加到网页内 语法:
document.createElement('标签名')
  1. 追加节点:把创建的新的节点放入到指定的元素内部

插入到父元素的最后一个子元素:

children.appendChild(要插入的元素)

插入到父元素中某个子元素的前面:

父元素.insertBefore(要插入的元素,在哪个元素前面)

例1:

<body>
    <ul>
        <li>我是第一个li</li>
    </ul>
    <script>
        //1.创建节点
        const div = document.createElement('div')
        //2.追加节点 作为最后一个子元素
        document.body.appendChild(div)

        //1.获取父元素
        const ul = document.querySelector('ul')
        //2.创建节点
        const li = document.createElement('li')
        li.innerHTML = '我才是第一个li'
        //3.追加节点 插入到ul中第一个li的前面
        ul.insertBefore(li,ul.children[0])
    </script>
</body>

2.4 复制/克隆节点

克隆节点的步骤

  1. 复制一个原有的节点
元素.cloneNode(布尔值)
  1. 把复制的节点放入到指定的元素内部

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

  • 若为true,则代表克隆时会包含后代节点一起克隆(深克隆)
  • 若为false,则代表克隆时不包含后代节点(浅克隆)
  • 默认为false

例:点击插入节点

<body>
  <h3>插入节点</h3>
  <p>在现有 dom 结构基础上插入新的元素节点</p>
  <hr>
  <!-- 普通盒子 -->
  <div class="box"></div>
  <!-- 点击按钮向 box 盒子插入节点 -->
  <button class="btn">插入节点</button>
  <script>
    //点击按钮,在网页中插入节点
    const btn = document.querySelector('.btn')
    //给按钮添加点击事件
    btn.addEventListener('click', function () {
      //1.创建新的元素节点
      const p = document.createElement('p')
      p.innerText = '创建的新的p标签'
      p.className = 'info'
      
      //2.克隆原有DOM节点
      const p2 = document.querySelector('p').cloneNode(true)
      p2.style.color = 'red'

      //3.插入新节点和克隆节点
      document.querySelector('.box').appendChild(p)
      document.querySelector('.box').appendChild(p2)
    })
  </script>
</body>

2.4 删除节点

删除现有的DOM节点

  1. 由父节点删除子节点
  2. 指定要删除的子节点 语法:
父元素.removeChild(要删除的子元素)

例1:点击按钮删除节点

<body>
  <!-- 点击按钮删除节点 -->
  <button>删除节点</button>
  <ul>
    <li>HTML</li>
    <li>CSS</li>
    <li>Web APIs</li>
  </ul>

  <script>
    const btn = document.querySelector('button')
    btn.addEventListener('click', function () {
      // 获取 ul 父节点
      let ul = document.querySelector('ul')
      // 待删除的子节点
      let lis = document.querySelectorAll('li')
      // 删除节点
      ul.removeChild(lis[0])
    })
  </script>
</body>

例2:点击按钮删除节点另一种写法

<script>
  const btn = document.querySelector('button')
  btn.addEventListener('click', function () {
      // 获取 ul 父节点
      let ul = document.querySelector('ul')
      // 通过父子关系确定要删除的节点
      ul.removeChild(ul.children[0])
  })
</script>