Web APIs (4) - 笔记

Web APIs (4) - 笔记

进一步学习 DOM 相关知识,实现可交互的网页特效

  • 能够插入、删除和替换元素节点
  • 能够依据元素节点关系查找节点

1 日期对象

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

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

1.1 实例化

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

创建一个时间对象并获取时间:

  • 获得当前时间

    javascript 复制代码
    const date = new Date()
  • 获得指定时间

    javascript 复制代码
    const date = new Date('2023-04-05')
    console.log(date)
javascript 复制代码
// 1. 实例化
// const date = new Date(); // 系统默认时间
const date = new Date('2020-05-01') // 指定时间
// date 变量即所谓的时间对象

console.log(typeof date)

1.2 日期对象方法

javascript 复制代码
// 1. 实例化
const date = new Date();
// 2. 调用时间对象方法
// 通过方法分别获取年、月、日,时、分、秒
const year = date.getFullYear(); // 四位年份
const month = date.getMonth(); // 0 ~ 11
方法 作用 说明
getFullYear() 获得年份 获取四位年份
getMonth() 获得月份 取值为 0 ~ 11
getDate() 获取月份中的每一天 不同月份取值也不相同
getDay() 获取星期 取值为 0 ~ 6
getHours() 获取小时 取值为 0 ~ 23
getMinutes() 获取分钟 取值为 0 ~ 59
getSeconds() 获取秒 取值为 0 ~ 59

1.3 时间戳

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

算法:

  • 将来的时间戳 - 现在的时间戳 = 剩余时间毫秒数
  • 剩余时间毫秒数 转换为 剩余时间的 年月日时分秒 就是 倒计时时间

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

javascript 复制代码
// 1. 实例化
const date = new Date()
// 2. 获取时间戳
console.log(date.getTime())
// 还有一种获取时间戳的方法
console.log(+new Date())
// 还有一种获取时间戳的方法
console.log(Date.now())

获取时间戳的方法,分别为 getTime 和 Date.now 和 +new Date()

1.4 案例:毕业倒计时效果

需求:计算到下课还有多少时间。

分析:

①:用将来时间减去现在时间就是剩余的时间

②:核心:使用将来的时间戳减去现在的时间戳

③:把剩余的时间转换为天时分秒

注意:

1.通过时间戳得到是毫秒,需要转换为秒在计算

2.转换公式:

  • d = parseInt(总秒数/60/60/24); // 计算天数
  • h = parseInt(总秒数 / 60 / 60 % 24) // 计算小时
  • m = parseInt(总秒数 / 60 % 60); // 计算分数
  • s = parseInt(总秒数 % 60); // 计算当前秒数
html 复制代码
<!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: 80px;
      font-size: 23px;
    }

    .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">今天是2222年2月22日</p>
    <p class="title">下班倒计时</p>
    <p class="clock">
      <span id="hour">00</span>
      <i>:</i>
      <span id="minutes">25</span>
      <i>:</i>
      <span id="second">20</span>
    </p>
    <p class="tips">18:30:00下课</p>
  </div>
  <script>
    // 随机颜色函数
    // 1. 自定义一个随机颜色函数
    function getRandomColor(flag = true) {
      if (flag) {
        // 3. 如果是true 则返回 #ffffff
        let str = '#'
        let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
        // 利用for循环随机抽6次 累加到 str里面
        for (let i = 1; i <= 6; i++) {
          // 每次要随机从数组里面抽取一个  
          // random 是数组的索引号 是随机的
          let random = Math.floor(Math.random() * arr.length)
          // str = str + arr[random]
          str += arr[random]
        }
        return str

      } else {
        // 4. 否则是 false 则返回 rgb(255,255,255)
        let r = Math.floor(Math.random() * 256)  // 55
        let g = Math.floor(Math.random() * 256)  // 89
        let b = Math.floor(Math.random() * 256)  // 255
        return `rgb(${r},${g},${b})`
      }

    }

    // 页面刷新随机得到颜色
    const countdown = document.querySelector('.countdown')
    countdown.style.backgroundColor = getRandomColor()

    // 函数封装 getCountTime
    function getCountTime() {
      // 1. 得到当前的时间戳
      const now = +new Date()
      // 2. 得到将来的时间戳
      const last = +new Date('2023-5-1 18:30:00')
      // console.log(now, last)
      // 3. 得到剩余的时间戳 count  记得转换为 秒数
      const count = (last - now) / 1000
      console.log(count)
      // 4. 转换为时分秒
      // d=parseInt(总秒数/60/60/24);  // 计算天数
      // h = parseInt(总秒数 / 60 / 60 % 24)  // 计算小时
      // m = parseInt(总秒数 / 60 % 60);  // 计算分数
      // s = parseInt(总秒数 % 24);  // 计算当前秒数
      // let d = parseInt(count / 60 / 60 / 24);  // 计算天数
      let h = parseInt(count / 60 / 60 % 24)  // 计算小时
      h = h < 10 ? '0' + h : h
      let m = parseInt(count / 60 % 60);  // 计算分数
      m = m < 10 ? '0' + m : m
      let s = parseInt(count % 60);  // 计算当前秒数
      s = s < 10 ? '0' + s : s
      console.log(h, m, s)

      // 5. 把时分秒写到对应的盒子里面
      document.querySelector('#hour').innerHTML = h
      document.querySelector('#minutes').innerHTML = m
      document.querySelector('#second').innerHTML = s
    }
    // 先调用一次
    getCountTime()

    // 开启定时器
    setInterval(getCountTime, 1000)
  </script>
</body>

</html>

2 节点操作

2.1 DOM 节点

掌握元素节点创建、复制、插入、删除等操作的方法,能够依据元素节点的结构关系查找节点

DOM节点

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

节点类型:

  • 元素节点

    • 所有的标签 比如 body、div
    • html 是根节点
  • 属性节点

    • 所有的属性 比如 href
  • 文本节点

    • 所有的文本
  • 其他

2.2 查找节点

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

2.2.1 父子关系

html 复制代码
<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 只获取元素类型节点。
html 复制代码
<body>
  <table>
    <tr>
      <td width="60">序号</td>
      <td>课程名</td>
      <td>难度</td>
      <td width="80">操作</td>
    </tr>
    <tr>
      <td>1</td>
      <td><span>HTML</span></td>
      <td>初级</td>
      <td><button>变色</button></td>
    </tr>
    <tr>
      <td>2</td>
      <td><span>CSS</span></td>
      <td>初级</td>
      <td><button>变色</button></td>
    </tr>
    <tr>
      <td>3</td>
      <td><span>Web APIs</span></td>
      <td>中级</td>
      <td><button>变色</button></td>
    </tr>
  </table>
  <script>
    // 获取所有 button 节点,并添加事件监听
    const buttons = document.querySelectorAll('table button')
    for(let i = 0; i < buttons.length; i++) {
      buttons[i].addEventListener('click', function () {
        // console.log(this.parentNode); // 父节点 td
        // console.log(this.parentNode.parentNode); // 爷爷节点 tr
        this.parentNode.parentNode.style.color = 'red'
      })
    }
  </script>
</body>

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

2.2.2 兄弟关系

html 复制代码
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
    </ul>
    <script>
        // const ul = document.querySelector('ul')  // ul
        // console.log(ul.children)  // 得到伪数组 选择的是 亲儿子
        const li2 = document.querySelector('ul li:nth-child(2)')
        console.log(li2.previousElementSibling)  // 上一个兄弟
        console.log(li2.nextElementSibling)  // 下一个兄弟
    </script>
</body>

结论:

  • previousElementSibling 获取前一个节点,以相对位置查找节点,实际应用中非常灵活。
  • nextElementSibling 获取后一个节点,以相对位置查找节点,实际应用中非常灵活。

2.3 插入节点

在已有的 DOM 节点中插入新的 DOM 节点时,需要关注两个关键因素:首先要得到新的 DOM 节点,其次在哪个位置插入这个节点。

如下代码演示:

html 复制代码
<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. 获得一个 DOM 元素节点
      const p = document.createElement('p')
      p.innerText = '创建的新的p标签'
      p.className = 'info'
      
      // 复制原有的 DOM 节点
      const p2 = document.querySelector('p').cloneNode(true)
      p2.style.color = 'red'

      // 2. 插入盒子 box 盒子
      document.querySelector('.box').appendChild(p)
      document.querySelector('.box').appendChild(p2)
    })
  </script>
</body>

结论:

  • createElement 动态创建任意 DOM 节点。

  • cloneNode 复制现有的 DOM 节点,传入参数 true 会复制所有子节点。

  • appendChild 在末尾(结束标签前)插入节点。

再来看另一种情形的代码演示:

html 复制代码
<body>
  <h3>插入节点</h3>
  <p>在现有 dom 结构基础上插入新的元素节点</p>
	<hr>
  <button class="btn1">在任意节点前插入</button>
  <ul>
    <li>HTML</li>
    <li>CSS</li>
    <li>JavaScript</li>
  </ul>
  <script>
    // 点击按钮,在已有 DOM 中插入新节点
    const btn1 = document.querySelector('.btn1')
    btn1.addEventListener('click', function () {

      // 第 2 个 li 元素
      const relative = document.querySelector('li:nth-child(2)')

      // 1. 动态创建新的节点
      const li1 = document.createElement('li')
      li1.style.color = 'red'
      li1.innerText = 'Web APIs'

      // 复制现有的节点
      const li2 = document.querySelector('li:first-child').cloneNode(true)
      li2.style.color = 'blue'

      // 2. 在 relative 节点前插入
      document.querySelector('ul').insertBefore(li1, relative)
      document.querySelector('ul').insertBefore(li2, relative)
    })
  </script>
</body>

结论:

  • createElement 动态创建任意 DOM 节点。

  • cloneNode 复制现有的 DOM 节点,传入参数 true 会复制所有子节点。

  • insertBefore 在父节点中任意子节点之前插入新节点。

2.4 删除节点

删除现有的 DOM 节点,也需要关注两个因素:首先由父节点删除子节点,其次是要删除哪个子节点。

html 复制代码
<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>

结论:

  • removeChild 删除节点时一定是由父子关系。
  • 如不存在父子关系则删除不成功。
  • 删除节点和隐藏节点(display:none)有区别的:隐藏节点还是存在的,但是删除,则从html中删除节点。

3 M端事件

触屏touch事件 说明
touchstart 手指触摸到一个 DOM 元素时触发
touchmove 手指在一个 DOM 元素上滑动时触发
touchend 手指从一个 DOM 元素上移开时触发
html 复制代码
<!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>
        div {
            width: 300px;
            height: 300px;
            background-color: pink;
        }
    </style>
</head>

<body>
    <div></div>
    <script>
        const div = document.querySelector('div')
        // 1. 触摸
        div.addEventListener('touchstart', function () {
            console.log('开始摸我了')
        })
        // 2. 离开
        div.addEventListener('touchend', function () {
            console.log('离开了')
        })
        // 3. 移动
        div.addEventListener('touchmove', function () {
            console.log('一直摸,移动')
        })
    </script>
</body>

</html>

4 插件

插件:就是别人写好的一些代码,我们只需要复制对应的代码,就可以直接实现对应的效果。

学习插件的基本过程:

相关推荐
夫琅禾费米线3 分钟前
leetcode2650. 设计可取消函数 generator和Promise
开发语言·javascript·leetcode·ecmascript
寒雒1 小时前
【Python】实战:实现GUI登录界面
开发语言·前端·python
独上归州1 小时前
Vue与React的Suspense组件对比
前端·vue.js·react.js·suspense
战族狼魂1 小时前
html+js实现图片的放大缩小等比缩放翻转,自动播放切换,顺逆时针旋转
javascript·css·html
Komorebi⁼1 小时前
Vue核心特性解析(内含实践项目:设置购物车)
前端·javascript·vue.js·html·html5
明月清风徐徐1 小时前
Vue实训---0-完成Vue开发环境的搭建
前端·javascript·vue.js
SameX1 小时前
HarmonyOS Next 企业数据备份与恢复策略
前端·harmonyos
SameX1 小时前
HarmonyOS Next 企业数据传输安全策略
前端·harmonyos
daopuyun1 小时前
LoadRunner小贴士|开发Web-HTTP/HTML协议HTML5相关视频应用测试脚本的方法
前端·http·html
李先静1 小时前
AWTK-WEB 快速入门(1) - C 语言应用程序
c语言·开发语言·前端