Web APIs 知识总结【节点操作】

118 阅读4分钟

节点操作

节点操作

Dom 节点

  • 定义:DOM 树内每一个内容都被称之为节点

  • 类型

    1. 元素节点

      • 所有的标签(如 bodydivp 等)

      • html 是根节点

    2. 属性节点

      • 所有的属性(如 srctitleclass 等)
    3. 文本节点

      • 所有的文本(包含文字、空格、换行等)
    4. 其他

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

查找节点

  • 节点关系

    1. 父节点

      子元素.parentNode
      
      • 得到的是离元素最近的那个父级

      • 找不到返回空

    2. 子节点

      • 得到所有子节点,包括元素节点和文本节点

        parentNode.childNodes
        
      • 获取所有元素节点,不包括文本和注释

        parentNode.children
        

      注意:

      返回的是一个伪数组,但不能使用 forEach 进行遍历

    3. 兄弟节点

      • 兄弟节点(包括元素节点或文本节点等)

        1. 下一个兄弟节点

          nextSibling
          
        2. 上一个兄弟节点

          previousSibling
          
      • 兄弟元素节点

        1. 下一个兄弟元素节点

          nextElementSibling
          
        2. 上一个兄弟元素节点

          previousElementSibling
          

增加节点

  1. 创建节点
let result = document.createElement('标签');
  • 括号内填标签,需要加引号

  • 创建完节点后,要对元素设置内容和样式

    • 内容设置:
      .innerHTML、.innerText
      
    • 样式设置:
      .classList、.style
      
  1. 添加节点

    • 插入

      node.insertBefore(child,指定元素)
      

      node 为父级元素,child 为子级元素(或刚创建的元素节点)

      要求:

      1. 在父级元素的指定子元素前插入元素
      2. 如果不填指定元素则报错
      3. 如果找不到指定元素(如只填 null)则默认是 appendChild 的效果
    • 追加

      node.appendChild(child)
      

      node 为父级元素,child 为子级元素(或刚创建的元素节点)

      要求:

      1. 在父级元素末尾追加元素,类似于 push
      2. 追加的节点可以是新创建的 也可以是页面上已经存在 (移动节点)
  2. 克隆节点

    用于需要创建一个复杂的标签,前提: 页面上有一个模板节点

     node.cloneNode()
    
    • 括号内为空或 false,则为浅拷贝(即只复制标签,不复制里面的内容)

    • 括号内为 true,则为深度拷贝(即既复制标签,又复制里面的内容)

    与添加节点的区别:

    添加节点的两个方法是移动式,即会把原节点从原来的地方删除,移动到指定位置;克隆则是克隆一个新的节点。

删除节点

  • 通过父元素删除

    parent.removeChild(child)
    

    删除节点和隐藏节点( display:none ) 有区别的: 隐藏节点还是存在的,但是删除,则从 html 中删除节点

    注意:

    如不存在父子关系则删除不成功,一定要是父子关系,不能爷爷删孙子。

  • 自己删除自己

      node.remove()
    


时间对象

用来表示时间的对象,可以得到当前系统时间

实例化

  • 定义

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

  • 获取方法

     let date = new Date()
     console.log(date.getTime())			
    
    1. 获取当前日期
      let date = new Date()
      
    2. 获取指定日期
      let date = new Date('2021-1-22')
      

时间对象方法

获取日期对象的每一个部分代码
获取年getFullYear()
获取月getMonth() + 1
获取日getDate()
获取时getHours()
获取分getMinutes()
获取秒getSeconds()

时间戳

  • 定义

    是指某一具体时间(如1970年01月01日00时00分00秒)至现在的毫秒数。

    它是一种特殊的计量时间的方式。

  • 获取方式

  1.  let date = new Date()
     console.log(date.getTime())					
    
  2.  console.log(+new Date())
    
  3.  console.log(Date.now())
    

    注意:

    • 方法三只能得到当前的时间戳。
    • 前面两种可以返回指定时间的时间戳,无需实例化。


总结

节点操作.png



今日案例

学成在线数据渲染

  1. 说到渲染就会有数据和结构的参与,数据在 data.js 文件中,结构已经提供
  2. 渲染的本质就是:将数据生成动态结构的过程--本质就是以前的遍历拼接
  3. 遍历数据源,每个数据对象生成一个 li 标签 : 创建li元素,设置内容
  4. 将创建好的 li 标签追加到页面的指定结构中
        let ul = document.querySelector('ul.clearfix')
        
        // 循环遍历数组中的数据
        data.forEach((element, index) => {
            let li = document.createElement('li')
            // 用模板字符串为创建好的li动态添加内容
            li.innerHTML = `<img src="${data[index].src}" alt="" />
                    <h4>
                        ${data[index].title}
                    </h4>
                    <div class="info">
                        <span>高级</span> • <span>${data[index].num}</span>人在学习
                    </div>`
            // 渲染到页面上
            ul.appendChild(li)
        });

注意事项

这里容易犯一个错误, li 必须是一个元素,才能用 appendChild 语句添加到页面中,如果在给 li 赋值时漏写了 .innerHTML 或者在最后 ul.appendChild(li) 括号中加了双引号,此时的 li 变成了字符串,添加会报错。

Failed to execute 'insertBefore' on 'Node': >parameter 1 is not of type 'Node'.

微博发布与删除

需求1

  1. 注册 input 事件
  2. 将文本的内容的长度赋值给对应的数值
  3. 表单的 maxlength 属性可以直接限制在200个数之间

需求2

  1. 克隆预定义好的模板,将模板的 hidden 属性设置为 false , 并最终展示到页面上
  2. 判断如果内容为空,则提示不能输入为空, 并且直接return
  3. 防止输入无意义空格, 使用字符串 .trim() 去掉首尾空格, 并将表单的value值设置为空字符串

需求3

  1. 获取文本域的内容, 赋值给由模板克隆出来的新标签里面的 content.innerText
  2. 随机获取数据数组里面的内容, 替换 newNode 的图片和名称
  3. Math.random()* (n + 1) 利用时间对象将时间动态化

需求4

  1. 在事件处理函数里面获取点击按钮,注册点击事件 易错点: 必须在事件里面获取,外面获取不到
  2. 删除对应的元素 (通过this获取对应的那条需要删除的元素)

需求5

  1. 将表单域内容重置为空
  2. 将userCount里面的内容重置为0
  • 封装好的时间函数

     let dateFormat = function() {
         let date = new Date()
         let year = date.getFullYear()
         let month = date.getMonth() + 1
         let day = date.getDate()
         let hour = date.getHours()
         let minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
         let second = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
    
         return `${year}-${month}-${day} ${hour}:${minute}:${second}`
     }
    
  • 显示字数

     let useCount = document.querySelector('.useCount')
     let txt = document.querySelector('textarea')
    
     txt.addEventListener('input', function() {
         let text = this.value
         useCount.innerHTML = text.trim().length
     })
     txt.addEventListener('focus', function() {
         this.placeholder = `发个友善的评论见证当下~`
     })
     txt.addEventListener('blur', function() {
         if (this.value.trim().length === 0) {
             this.placeholder = `不发也没关系,继续保持友善哦`
         }
     })
    
  • 点击发布按钮发布微博,点击 X 号删除微博,如果为空弹出提示。

     let list = document.querySelector('#list')
     let area = document.querySelector('#area')
     let useCount = document.querySelector('#useCount')
     let send = document.querySelector('#send')
     area.focus()
     send.addEventListener('click', function() {
         if (area.value === '') {
             alert('空的哦')
             return
         }
         let txt = area.value.trim()
         let index = parseInt(Math.random() * dataArr.length)
         let li = document.createElement('li')
         li.innerHTML = `<div class="info">
           <img class="userpic" src="${dataArr[index].imgSrc}" />
           <span class="username">${dataArr[index].uname}</span>
           <p class="send-time">发布于 ${dateFormat()}</p>
         </div>
         <div class="content">${txt}</div>
         <span class="the_del">X</span>`
         list.insertBefore(li, list.children[0])
    
         let del = document.querySelector('.the_del')
         del.addEventListener('click', function() {
             del.parentNode.remove()
         })
    
         area.value = ''
         useCount.innerHTML = 0
     })
    
  • 点击回车键发布微博,业务和点击发布按钮一样,因此可直接调用发布按钮的点击事件回调函数即可。

    area.addEventListener('keydown', function(e) {
        if (e.key === 'Enter') {
            send.click()
        }
    })