Web APIs-DOM--- 节点操作及时间对象

116 阅读2分钟

节点操作

DOM 节点

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

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

  3. 文本节点:所有的文本

  4. 其他

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

image-20220407194103122

查找节点

  1. 父节点
<body>
    <div>
        <img src="./imgs/01.png" alt="" class="close">
        <img src="./imgs/02.png" alt=""  class="erweima">
    </div>

    <script>
        // 语法:子元素.parentNode 
        // 返回最近一级的父节点,找不到则返回null

        // 获取dom元素
        let close = document.querySelector('.close')
        let erweima = document.querySelector('.erweima')
        // 绑定点击事件
        close.addEventListener('click',function () {
            // 通过父节点来修改样式
            this.parentNode.style.display='none'
        })
    </script>
</body>
  1. 子节点

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

    children:仅获得所有元素节点(标签,文本等),且返回一个伪数组

<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>

    <script>
                            
        // 获取Dom元素
        let ulList = document.querySelectorAll('ul')

        // 遍历数组 
        for (let index = 0; index < ulList.length; index++) {
            // 绑定ulList数组中的每个元素
            ulList[index].addEventListener('click',function () {
                // 再把children 获取到中的每一个li标签
                for (let j = 0; j < this.children.length; j++) {
                    // 点击事件触发,把li标签隐藏
                    this.children[j].style.display = 'none'                   
                }             
            })       
        }
    </script>
</body>
  1. 兄弟节点

    下一个兄弟节点:nextElementSibling 属性

    上一个兄弟节点:previousElementSibling 属性

<body>
    <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>
        // 获取DOM元素
        let liList = document.querySelectorAll('li')
        // 遍历获取每一个li
        for (let index = 0; index < liList.length; index++) {
            // 给每一个li标签绑定点击事件
            liList[index].addEventListener('click',function () {
                // 点击事件触发,改变被点击的上一个li标签变颜色
                this.previousElementSibling.style.color = 'pink'
                // 点击事件触发,改变被点击的下一个li标签变背景颜色
                this.nextElementSibling.style.backgroundColor = 'aqua'
            })
            
        }
    </script>
</body>

增加节点

  1. 创建节点:即创造出一个新的网页元素,再添加到想要添加的位置
    <style>
        ul {
            height: 200px;
            background-color: pink;
        }
    </style>
</head>
<body>
    <ul></ul>

    <script>
        // 语法:document.createElement('标签名')

        // 1 创建一个 li 标签 注意:生成不会直接显示,而是储存在浏览器中
        let li = document.createElement('li')
        // 添加li标签的文本内容
        li.innerText = '啥玩意'
        
        let ul = document.querySelector('ul')
        // 2.把Li插入到 ul标签中
        ul.appendChild(li)  
    </script>
</body>
  1. 追加节点
<body>
    <ul class="left">
        <li>a</li>
        <li>b</li>
        <li>c</li>
        <li>d</li>
    </ul>
    <ul class="right">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>

    <script>
        // 语法:父元素.

        // 获取DOM元素insertBefore(要插入的元素,在哪个元素前面)
        let c = document.querySelector('.left li:nth-child(3)')
        let two = document.querySelector('.right li:nth-child(2)')
        let right = document.querySelector('.right')

        // 要插入的父元素.insertBefore(要插入的元素,哪个元素的前面)
        right.insertBefore(c,two)
    </script>
</body>
  1. 克隆节点

    cloneNode会克隆出一个跟原标签一样的元素,括号内可以输入布尔值

    输入true,代表克隆时会包含后代节点一起克隆,又叫深拷贝

    输入false,代表克隆时不包含后代节点,又叫浅拷贝,默认值为false

    <style>
        .box {
            width: 500px;
            height: 500px;
            background-color: pink;
            border: 1px solid #000;
        }
    </style>
</head>
<body>
    <div class="box">
        <button>开始</button>
        <button>结束</button>
    </div>

    <script>
        let box = document.querySelector('.box')

        // 开始克隆节点
        let news = box.cloneNode() //不赋值的情况下,默认是浅克隆  不会把后代节点一起克隆

        //let news = box.cloneNode(true) //赋值true 就是深克隆 代表会把后代节点一起克隆

        // 插入body标签中
        document.body.appendChild(news)
    </script>
</body>

删除节点

​ 在 JavaScript动态生成的页面的中,若某一个节点在页面使用中不需要时,可以通过删除节点的方式来删除它

​ 如果父子级关系不成立,就会删除失败

​ 删除节点和隐藏节点(display:none)的区别: 隐藏节点隐藏后还是会存在HTML里,但是删除,就是从HTML中彻底删除节点

<body>
    <button>点击删除</button>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
    </ul>

    <script>
        // 语法:父元素.removeChild(要删除的子元素)
        //     父元素.remove()  删除自己
        let button = document.querySelector('button')
        let ul = document.querySelector('ul')
        // li放在外面,就只能执行一次
        let li = document.querySelector('li')
        
        button.addEventListener('click',function () {
            // li放在里面获取,点击一次就重新执行一次
            // let li = document.querySelector('li')

            // 删除父元素的指定子元素
            // ul.removeChild(li)

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

时间对象

实例化

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

​ 获得当前时间:let 变量名 =new Date() ←固定写法

​ 获得指定时间:let 变量名 =new Date('2012-12-12') ←固定写法

时间对象方法

时间对象中的常用方法

方法作用说明
getFullYear()获得年份获取四位年份
getMonth()获得月份取值为 0 ~ 11
getDate()获取月份中的每一天不同月份取值也不相同
getDay()获取星期取值为 0 ~ 6
getHours()获取小时取值为 0 ~ 23
getMinutes()获取分钟取值为 0 ~ 59
getSeconds()获取秒取值为 0 ~ 59
<body>
    <h1></h1>
    <script>
        
        // 获取dom元素
        let h1 = document.querySelector('h1')
        
        // 添加定时器
        setInterval(function () {
            let nowDate = new Date()
            let year = nowDate.getFullYear()
            let month= nowDate.getMonth()
            let day= nowDate.getDay()
            let hours= nowDate.getHours()
            let minutes= nowDate.getMinutes()
            let seconds= nowDate.getSeconds()
            h1.innerHTML=`
            ${year}-${month}-${day} ${hours}:${minutes}:${seconds}
            `
        },)
    </script>
</body>

时间戳

什么是时间戳?

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

时间戳的三种获取方式

<body>
    <script>
        // 三种方式获取时间戳

        // 方式一
        // let date = new Date()
        // console.log(date.getTime());

        // 方式二
        // console.log(+new Date());

        // 方式三
        console.log(Date.now());

        // 作用:一般用来生成一个不会重复的随机数
    </script>
</body>

综合案例

学成在线案例渲染---节点实现

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport"
    content="width=device-width, initial-scale=2.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
  <title>index.html</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">
      </ul>
    </div>
  </div>
  <!-- 来引入外部的js -->
  <script src="./data/data.js"></script>

  <script>

    let clearfix = document.querySelector('ul')
    // 遍历data数组
    for (let index = 0; index < data.length; index++) {
      let li = document.createElement('li')
      // 创建标签
      let img = document.createElement('img')
      // 添加属性
      img.src = data[index].src
      let h4 = document.createElement('h4')
      h4.innerText = data[index].title
      let div = document.createElement('div')
      div.classList.add('info')
      let span1 = document.createElement('span')
      span1.innerText = '高级'
      let span2 = document.createElement('span')
      span2.innerText = data[index].num


      // 创建文本节点内容
      let text1 = document.createTextNode(' • ')
      let text2 = document.createTextNode('人在学习')


      // 按顺序进行最后封装
      div.append(span1, text1, span2, text2);
      li.append(img, h4, div)
      clearfix.appendChild(li)
    }   
  </script>
</body>

</html>

发布微博综合案例

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <link rel="stylesheet" href="css/weibo.css" />
  </head>

  <body>
    <div class="w">
      <div class="controls">
        <img src="images/tip.png" alt="" /><br />
        <textarea
          placeholder="说点什么吧..."
          id="area"
          cols="30"
          rows="100"
          maxlength="200"
        ></textarea>
        <div>
          <span class="useCount">0</span>
          <span>/</span>
          <span>200</span>
          <button id="send">发布</button>
        </div>
      </div>
      <div class="contentList">
        <ul>
          
        </ul>
      </div>
    </div>
    <script>
      let dataArr = [
        { uname: '司马懿', imgSrc: './images/9.5/01.jpg' },
        { uname: '女娲', imgSrc: './images/9.5/02.jpg' },
        { uname: '百里守约', imgSrc: './images/9.5/03.jpg' },
        { uname: '亚瑟', imgSrc: './images/9.5/04.jpg' },
        { uname: '虞姬', imgSrc: './images/9.5/05.jpg' },
        { uname: '张良', imgSrc: './images/9.5/06.jpg' },
        { uname: '安其拉', imgSrc: './images/9.5/07.jpg' },
        { uname: '李白', imgSrc: './images/9.5/08.jpg' },
        { uname: '阿珂', imgSrc: './images/9.5/09.jpg' },
        { uname: '墨子', imgSrc: './images/9.5/10.jpg' },
        { uname: '鲁班', imgSrc: './images/9.5/11.jpg' },
        { uname: '嬴政', imgSrc: './images/9.5/12.jpg' },
        { uname: '孙膑', imgSrc: './images/9.5/13.jpg' },
        { uname: '周瑜', imgSrc: './images/9.5/14.jpg' },
        { uname: '老夫子', imgSrc: './images/9.5/15.jpg' },
        { uname: '狄仁杰', imgSrc: './images/9.5/16.jpg' },
        { uname: '扁鹊', imgSrc: './images/9.5/17.jpg' },
        { uname: '马可波罗', imgSrc: './images/9.5/18.jpg' },
        { uname: '露娜', imgSrc: './images/9.5/19.jpg' },
        { uname: '孙悟空', imgSrc: './images/9.5/20.jpg' },
        { uname: '黄忠', imgSrc: './images/9.5/21.jpg' },
        { uname: '百里玄策', imgSrc: './images/9.5/22.jpg' },
      ];
        
      let send = document.querySelector('#send');
      let ul = document.querySelector('ul');
      
      send.addEventListener('click',function () {
        // 调用封装好的函数
        let user = getUser()
        // 字符串拼接
        let htmlStr = `
        <li>
            <div class="info">
              <img class="userpic" src=${user.imgSrc}>
              <span class="username">${user.uname}</span>
              <p class="send-time">发布于 ${getNowTime()}</p>
            </div>
            <div class="content">${area.value}</div>
            <span class="the_del">X</span>
          </li> 
        `
        // 每点击一次  就在原有的标签基础上 拼接多一个标签
        ul.innerHTML += htmlStr
      })

      // 给文本域绑定input事件
      area.addEventListener('input',function () {
        // 设置span1的数字随着输入的变化增加
        let length = this.value.length
        useCount.innerText = length
      })

      // 封装区间随机数
      function getUser() {
      
        // 随机的获取数组中的元素 获取对应区间的下标
        // 公式 Math.round(Math.random()*(max-min)+min)
        // max等于数组长度
         let index = Math.round(Math.random() * (dataArr.length-1))
          let user = dataArr[index]
          return user
      }
      
      // 封装实时时间
      function getNowTime() {
        let nowDate = new Date()
            let year = nowDate.getFullYear()
            let month= nowDate.getMonth()
            let day= nowDate.getDay()
            let hours= nowDate.getHours()
            let minutes= nowDate.getMinutes()
            let seconds= nowDate.getSeconds()

            // 判断 月日时分秒 <10的时候在前面添加0
            month = month < 10 ? '0' + month : month
            day = day < 10 ? '0' + day : day 
            hours = hours < 10 ? '0' + hours : hours 
            minutes = minutes < 10 ? '0' + minutes : minutes 
            seconds = seconds < 10 ? '0' + seconds : seconds 

            return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
      }
    </script>
  </body>
</html>