webAPI知识回顾

160 阅读10分钟

webAPI

  • 作用:使用JS去操作html和浏览器
  • 分类:DOM,BOM

DOM树

作用:文档树直观的体现了标签与标签之间的关系

获取dom对象

<div>123</div>
<div>456</div>
<script>
    let num=document.querySelector("div")
    console.log(num)
    console.dir(num)
</script>
  • 获取方式:**document.querySelector(**选择器)
  • 只能获取第一个满足条件的标签
  • 找不到则返回null
  • 想要输出dom元素,用console.dir,不再使用console.log

querySelectorAll

  1. 获取所有同名标签
  2. 能找到则返回dom元素
  3. 找不到则返回null
  4. 结果无论如何都是返回数组

设置文本内容方式(动态设置)

document.write()

  • 只能在body标签中写,极少使用

innerText

  • 只能设置文本,不能解析html字符串

innerHTML

  • 可以设置文本,也可以解析html字符串

属性

刷新随机显示图片案例

<body>
    <img src="" width="100%" alt="">
    <script>
        let image=document.querySelector('img')
        let i=Math.round(Math.random()*8+2)
        console.log(i)
        image.src=`./wallpaper/${i}.jpg`
    </script>
</body>

设置修改元素样式属性

  • 修改样式通过style属性引出

  • 属性有连接符-,需要转换为小驼峰命名法

  • 赋值的时候,不要忘记加css单位

    • <body>
          <div>修改样式属性</div>
          <script>
              let div=document.querySelector('div')
              div.style.fontSize="50px"
              div.style.color="pink"
              div.style.backgroundColor="#000"
          </script>
      </body>
      
    • 这种方法只能修改行内式,麻烦

  • 刷新页面随机颜色

    • let bd=document.querySelector('body')
      function getRandom(min,max){
          return Math.round(Math.random()*max-min+min)
      }
      let c1=getRandom(0,255)
      let c2=getRandom(0,255)
      let c3=getRandom(0,255)
      bd.style.backgroundColor=`rgb(${c1},${c2},${c3})`
      

通过类名修改样式

  • className:先清空原有的dom元素类名,再单独添加新类名
  • 如果需要同时添加多个class,以空格分割
<style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        .box{
            width: 200px;
            height: 200px;
            background-color: red;
        }
        .radius{
            border-radius: 50%;
            background-color: yellow;
        }
</style>
<body>
    <div></div>
    <script>
        let div=document.querySelector("div")
        div.className="box radius"
    </script>
</body>

操作类

  • 元素.classList.add('类名')——追加一个类
  • 元素.classList.remove('类名')——删除一个类
  • 元素.classList.toggle('类名')——切换一个类
  • 操作多个类——('类名', '类名')

定时器

  • 开启定时器

  • 开启之后会返回一个定时器ID

  • 同时开启多个定时器,关闭只会关闭最后一个定时器

  • 此时要用到节流:开启一个定时器,不允许开启另外一个定时器

    • 开启时按钮禁用,关闭时按钮启用

    • <body>
          <button class="start">开始点名</button>
          <button class="stop">停止点名</button>
          <h3></h3>
          <script>
              let start=document.querySelector(".start")
              let stop=document.querySelector(".stop")
              let h3=document.querySelector("h3")
              let arr=['沙煲粉','酸菜鱼','海底捞','麦当劳','吃草','烧烤','奶茶','果茶','饮茶']
              let i
              let nameId
              start.addEventListener('click',function (){
                  start.disabled=true
                  nameId=setInterval(function (){
                      i=Math.round(Math.random()*(arr.length-1))
                      console.log(i)
                      h3.innerText=arr[i]
                  },50) 
              })
              stop.addEventListener('click',function (){
                  clearInterval(nameId)
                  start.disabled=false
              })
          </script>
      </body>
      
    • 节流:先停止定时器

    • <body>
          <button class="start">开始点名</button>
          <button class="stop">停止点名</button>
          <h3></h3>
          <script>
              let start=document.querySelector(".start")
              let stop=document.querySelector(".stop")
              let h3=document.querySelector("h3")
              let arr=['沙煲粉','酸菜鱼','海底捞','麦当劳','吃草','烧烤','奶茶','果茶','饮茶']
              let i
              let nameId
              start.addEventListener('click',function (){
                  if(nameId){
      				clearInterval(nameId)
                  }
                  nameId=setInterval(function (){
                      i=Math.round(Math.random()*(arr.length-1))
                      console.log(i)
                      h3.innerText=arr[i]
                  },50) 
              })
              stop.addEventListener('click',function (){
                  clearInterval(nameId)
              })
          </script>
      </body>
      
    • <script>
      function log() {
          console.log('你被强化了,快上')
      }
      //一秒钟调用一次log函数
      setInterval(log,1000)
      </script>
      
  • 关闭清除定时器

  • 通过定时器ID

    • let i=0
      let timeId=setInterval(function (){
          i++
          console.log('你好啊')
          if(i===30) clearInterval(timeId)
      },500)
      
      

设置表单属性

  • 输入框内容——*.value=''
  • 复选框选定状态——*.checked=true/false
  • 按钮禁用状态——*.disabled=true/false
  • 下拉框默认选中——*.selected=true
  • 文本域
    • 获取内容
      • 原样获取内容——.value
      • 获取html转义——.innerHTML
    • js设置内容
    • .value
    • .innerText
    • .innerHTML

事件

  • 单机一个按钮等就是事件

  • 事件监听

    • 程序检测事件产生,触发事件立即调用函数响应,也称为注册事件
  • 语法

    • //获取元素
      let btn=document.querySelector('button')
      //事件监听
      btn.addEventListener('click',function(){
      	alert('被点击了')
      })
      
      
  • 事件监听三要素

    • 事件源:被触发的dom元素
    • 事件:用什么方式出发,比如单击,鼠标经过等
    • 事件调用的函数:要做什么
  • 事件区别

    • addEventListener——对一个事件类型,绑定多个处理函数(常用)
    • on+事件——对一个事件类型,只能绑定一个处理函数

事件类型

  • click——点击
  • mouseenter——鼠标经过
  • mouseover——鼠标经过
  • mouseleave——鼠标离开
  • mouseout——鼠标离开
  • focus——获得焦点
  • blur——失去焦点
  • Keydown——键盘按下触发
  • Keyup——键盘抬起触发
  • input——用户输入事件

环境对象

环境对象指的是函数内部特殊的变量this,代表着当前函数运行时所处的环境

重点:弄清楚this的指向

  • 函数的调用方式不同,this指代的对象也不同
  • 粗略规则:谁调用,this就是谁

排他思想

实际开发经常运用的技巧

  1. 先让其他元素恢复原样
  2. 再把样式添加到需要的元素身上
<body>
    <ul>
        <li>NO.1</li>
        <li>NO.2</li>
        <li>NO.3</li>
        <li>NO.4</li>
        <li>NO.5</li>
        <li>NO.6</li>
        <li>NO.7</li>
        <li>NO.8</li>
    </ul>
    <script>
        let lis=document.querySelectorAll("li")
        for (let index = 0; index < lis.length; index++) {
            lis[index].addEventListener('click',function (){
                for (let index = 0; index < lis.length; index++) {
                    lis[index].style.backgroundColor="#fff"
                }
                this.style.backgroundColor="pink"
            })
        }
    </script>
</body>

DOM节点

DOM树当中每一个内容都称为一个节点

  • 元素节点
  • 属性节点
  • 文本节点

查找节点

  • *.parentNode
    • 获取父元素
  • *.children(重点)
    • 获取所有子元素
    • 返回的还是一个伪数组
  • *.childNodes(了解)
  • *.nextElementSibling
  • *.previousElementSibling

增加节点

  1. 先创建一个内存当中的元素

    • // 创建一个li标签节点
      let newLi=document.createElement('li')
      // 为新节点添加样式文字
      newLi.innerText='你们好,我是新来的猪肉'
      newLi.style.backgroundColor='yellow'
      
      
  2. 再把元素插入页面当中

    • // 新节点插入到页面
      let ul=document.querySelector('ul')
      ul.appendChild(newLi)
      
      
  3. *.append(a,b,c,d)——可以插入多个元素节点

  4. document.createTextNode("text")——创建文本节点

  5. 父元素.insertBefore(将要插入的节点,在谁之前)

    1. 功能类似appendChild

    2. 如果要插入元素已经存在,作用就是剪切粘贴

    3. 如果要插入元素是新创建,作用就是仅仅插入

    4. 即便父元素是空数组,也可以插入目标元素——*.insertBefore(待插入元素, null)

    5. <body>
          <ul class="left">
              <li>1</li>
              <li>2</li>
              <li>3</li>
              <li>4</li>
          </ul>
      
          <ul class="right">
              <li>a</li>
              <li>b</li>
              <li>c</li>
              <li>d</li>
          </ul>
          <script>
              let three=document.querySelector(".left li:nth-child(3)")
              let b=document.querySelector(".right li:nth-child(2)")
              let right=document.querySelector(".right")
      
              right.insertBefore(three,b)
          </script>
      </body>
      
      
克隆节点
// 克隆一个已有的元素节点
元素.cloneNode(布尔值)
  • cloneNode会克隆一个已有元素
    • 括号内为true,代表连后代节点一起克隆——深拷贝
    • 括号内为false,代表不克隆后代节点,只克隆本身——浅拷贝
    • 默认值false

删除节点

  • // 元素自删
    元素.remove()
    
  • // 删除子节点
    父元素.removeChild(要删除的元素)
    
  • 不存在父子关系则不成功

  • 删除与隐藏节点的区别

    • 隐藏节点:还存在节点
    • 删除节点:从html中删除节点

时间对象方法

时间对象返回的数据不能直接使用,要转换为实际开发常用格式

实例化时间对象

  • 代码中有new关键字,一般称为实例化
  • 创建一个事件对象并获取时间
// 实例化
let date = new Date()

时间戳

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())
    

事件

事件对象

对象里有事件触发时的相关信息

获取事件对象

  • 在事件绑定的回调函数的第一个参数就是事件对象
  • 一般命名为event,ev,e

常见属性

  • event.cilentX, event.cilentY
  • event.offsetX, event.coffsetY
  • key,不推荐用keycode

事件流

事件流指的是事件完整执行过程中的流动路径

  • 元素触发事件时,会经历两个阶段
    • 捕获阶段
      • 从父亲到儿子
    • 冒泡阶段(默认
      • 从儿子到父亲

修改事件流阶段

  • 事件绑定最后传入true或者false
    • true捕获阶段
    • false冒泡阶段(默认)往后开发阶段一般都是用默认冒泡阶段,不需要传入false

阻止冒泡

event.stopPropagation()

   <style>
        .a{
            width: 500px;
            height: 500px;
            background-color: red;
        }
        .b{
            width: 300px;
            height: 300px;
            background-color: yellow;
        }
        .c{
            width: 100px;
            height: 100px;
            background-color: blueviolet;
        }
        p{
            width: 500px;
            height: 500px;
        }
    </style>
</head>
<body>
    <p></p>
    <div class="a">grandfather
        <div class="b">father
            <div class="c">son</div>
        </div>
    </div>
    <script>
        const a=document.querySelector('.a')
        const b=document.querySelector('.b')
        const c=document.querySelector('.c')
        const p=document.querySelector('p')

        a.addEventListener("click", function (){
            console.log('a')
            p.style.backgroundColor="red"
        })
        b.addEventListener("click", function (){
            p.style.backgroundColor="yellow"
            console.log('b')
        })
        c.addEventListener("click", function (e){
            p.style.backgroundColor="blueviolet"
            console.log('c')
            e.stopPropagation()
        })
    </script>
</body>

事件委托

把业务委托给父元素

  • 简单粗暴法e.target获取触发的最底层元素

    • <body>
          <ul>
              <li>1</li>
              <li>2</li>
              <li>3</li>
              <li>4</li>
          </ul>
          <script>
              const ul=document.querySelector("ul")
              ul.addEventListener("click", function (e){
                  e.target.style.backgroundColor="red"
              })
          </s
      

阻止标签默认行为

  • a标签具有点击默认跳转功能

    • 通过e.preventDefault()阻止
  • form表单中type='submit'`默认有点击刷新行为

    • 阻止方法
      • 给标签注册事件添加e.preventDefault()
      • button按钮添加type="button"属性
      • input按钮添加type="button"属性
      • 把按钮移出form表单
  • 网页默认右键菜单

    •     <style>
              *{
                  margin: 0;
                  padding: 0;
                  box-sizing: border-box;
              }
              body{
                  height: 100vh;
              }
              .menu{
                  list-style: none;
                  border: 1px solid #999;
                  width: 120px;
                  position: fixed;
                  display: none;
                  font-size: 14px;
              }
              li{
                  padding: 8px;
              }
          </style>
      </head>
      <body>
          <ul class="menu">
              <li>添加桌面</li><hr>
              <li>壁纸动态</li><hr>
              <li>炫酷桌面</li><hr>
              <li>清理内存</li>
          </ul>
          <script>
              const menu=document.querySelector(".menu")
              document.body.addEventListener('contextmenu', function (e){
                  e.preventDefault()
                  menu.style.display='block'
                  menu.style.top=e.clientY+'px'
                  menu.style.left=e.clientX+'px'
              })
              document.body.addEventListener('click', function(){
                  menu.style.display='none'
              })
          </script>
      </body>
      

scroll事件

document.documentElement是根标签

<!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>
</head>
<body>
    <h1>1</h1>
		// 省略一万个h1标签
    <script>
        window.addEventListener("scroll", function (){
            console.log(document.documentElement.scrollTop)
        })
    </script>
</body>
</html>

加载事件

  • 加载外部资源完毕时触发的事件

  • 避免外部资源没有加载完,js代码找不到dom元素

  • 事件名:load

  • window添加load事件

    • //	页面加载事件
      window.addEventListener('load', function (){
      	// 执行的操作
      })
      
  • DOMContentLoaded事件(早期js代码写在head里面时用的)

  • 标签加载完毕就触发了

scroll家族

  • dom.scrollWidth包含可滚动的内容宽度(PC端不包括滚动条17px)
  • dom.scrollHeight包含可滚动的内容高度(PC端不包括滚动条17px)
  • dom.scrollTop元素上滚动距离
  • dom.scrollLeft元素左滚动距离
  • 注意
    • PC端的滚动条大小是17px
    • 移动端的滚动条不占大小

offset家族

  • dom.offsetWidth获取自身宽度(包括滚动条17px)
  • dom.offsetHeight获取自身高度(包括滚动条17px)
  • dom.offsetTop获取自身顶部到有定位父元素的距离
  • dom.offsetLeft获取自身左边到有定位父元素的距离

client家族

  • dom.clientWidth获取自身可视宽度(不包括滚动条17px)
  • dom.clientHeight获取自身可视高度(不包括滚动条17px)
  • dom.clientTop获取自身上边框宽度
  • dom.clientLeft获取自身左边框宽度
  • 没有右边框和下边框的获取代码undefined

第三方插件-swiper7-轮播图

  • 官方网址:www.swiper.com.cn/
  • 使用步骤(具体查看官方文档)
    1. 首先加载插件,需要用到的文件有swiper-bundle.min.js和swiper-bundle.min.css文件,不同Swiper版本用到的文件名略有不同。可下载Swiper文件或使用CDN
    2. 添加HTML内容。Swiper7的默认容器是'.swiper',Swiper6之前是'.swiper-container'。
    3. 你可能想要给Swiper定义一个大小,当然不要也行。
    4. 初始化Swiper。

延时器

延迟时间后执行

<!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;
        }
        .box{
            width: 300px;
            height: 300px;
            background-color: yellow;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 12px;
        }
    </style>
</head>
<body>
    <div class="box">
        男人,就要健身keep fit
    </div>
    <script>
        setTimeout(function () {
            document.querySelector(".box").style.display="none"
        },2000)
    </script>
</body>
</html>

BOM

location

  • location.href="http:/www.baidu.com"——实现跳转页面
  • location.href=location.href——页面刷新
  • location.reload(true)——强制刷新!
  • location.search获取url ? 后面一串字符
  • location.hashvue阶段,获取#后面一串字符

navigator

  • navigator数据类型是对象,存放着浏览器自身的信息

本地存储(面试

  • 数据存储在用户浏览器中
  • 设置,读取方便、甚至页面刷新不丢失数据
  • 容量较大,sessionStoragelocalStorage约5M左右

localStorage

  • 存储数据——localStorage.setItem(key, value)

  • 获取数据——localStorage.getItem(key)

  • 删除一条数据——localStorage.remove(key)

  • 清空所有数据——localStorage.clear()

  • 特点

    • 生命周期永久生效,除非手动删除,否则关闭页面也会存在
    • 可以多窗口**共享(**同一浏览器)
    • 存储形式为键值对
    • 存入复杂数据类型,引用数据类型会发生数据丢失
  • 改变颜色小案例

    • <body>
          <input type="color" name="" id="">
          <script>
              document.body.style.backgroundColor=localStorage.getItem('userColor')
              const inputColor=document.querySelector("input")
              inputColor.addEventListener("change", function () {
                  document.body.style.backgroundColor=this.value
                  localStorage.setItem('userColor', this.value)
              })
          </script>
      </body>
      

localStorage复杂数据

  1. 转换为字符串——JSON.stringify(),然后存入本地存储
  2. 拿到本地存储,再转换为原类型——JSON.parse()

sessionStorage

  • 特点
    • 生命周期为关闭浏览器窗口
    • 同一窗口共享数据
  • 其他基本和localStorage一致

元素属性

固有属性

标签固有属性通过dom.xxx可以获取到,也可以dom.getAttribute(属性名)

自定义属性

  • 设置自定义属性
    • dom.setAttribute(属性名, 属性值)
    • H5建议方式data-xxx——<a data-index="1" href=""></a>
  • 获取自定义属性
    • dom.getAttribute(属性名)
    • dom.dataset.xxx
  • 最强大
    • Attribute()

高阶函数

一个函数被当作形参使用时,就形成高阶函数

重绘和回流

  • 浏览器界面渲染
    1. 解析HTML,生成DOM树
    2. 同时解析CSS,生成样式规则
    3. 根据上述结果生成渲染树
    4. 进行布局layout(回流/重排):根据渲染树,得到节点几何信息(位置、大小尺寸)
      1. 渲染树元素大小结构布局改变时,浏览器会重新渲染文档,称为回流(重排)
    5. 进行绘制Painting(重绘):根据计算和获取的信息进行整个页面的绘制
      1. 由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时,称为重绘
    6. Display:展示在页面
    7. 重绘不一定引起回流,回流一定会引起重绘

事件解绑

dom.removeEventListener(事件名, 函数名)

不可以解绑注册了匿名函数的事件

字符串方法

  • 转大写

    • const str="abc?defg"
      console.log(str.toUpperCase())
      
  • 转小写

    • const str="abc?defg"
      console.log(str.toLowerCase())
      
  • 字符分割(返回数组)

    • const str="abc?defg"
      console.log(str.split(''))
      console.log(str.split('?'))
      

数组方法

  • 数组合并
    • arr1.concat(arr2)
  • 数组转字符串
    • arr1.join()

正则表达式

检测字符串中是否含有所需字符

const str = '有梦想,我小时候的梦想是长大了一定要娶一个跟电影明星一样漂亮的老婆,后来变了,变成我长大后一定要考上军校,当一个大将军,后来随着高考成绩的出现,又变了,变成了要下海经商,变成有钱人,结果发现不会骗人,太实诚,没有做生意的天赋,梦想又变了,变成一个科学家,研究人类生命的起源,让人人可以长生,永远可以陪伴自己最亲密的人,结果每天都被柴米油盐,衣食住行给牵累,什么也干不成,只能找一个养家糊口的工作,老老实实的上班下班!'

// 正则表达式是对象,不是字符串
const reg=/长大/

console.log(reg.test(str))

元字符

  • 边界符
    • ^开头
    • $结尾
  • 量词
    • *——出现0次或多次
    • +——出现1次或多次
    • ?——出现0次或1次
    • {n}——出现n次
    • {n,}——出现n次或多次
    • {n, m}——出现n次到m次
  • 字符
    • \d——匹配0-9之间的任一数字
    • \D——匹配所有0-9之外的字符
    • \w——匹配任意的字母、数字和下划线,相当于[A-Za-z0-9]
    • \W——匹配所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9]
    • \s——匹配空格(包括换行符、制表符、空格符等),相当于[\t\r\n\v\f]
    • \S——匹配所有空格之外的字符,相当于[^\t\r\n\v\f]
  • []
    • 中括号表示范围
    • [0-9] [a-z] [A-Z] [0-9a-zA-Z] [a-d]

微博发布案例

  • 原始人做法(操作节点

  • <!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>
              <!-- <li>
                <div class="info">
                  <img class="userpic" src="./images/9.5/06.jpg" />
                  <span class="username">张良</span>
                  <p class="send-time">发布于 2022-4-7 15:12:23</p>
                </div>
                <div class="content">sdfdf</div>
                <span class="the_del">X</span>
              </li> -->
            </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 text=document.querySelector("textarea")
          let useCount=document.querySelector(".useCount")
          // 获取发布按钮
          let send=document.querySelector("#send")
          // 获取ul元素
          let ul=document.querySelector("ul")
          // 文本框事件
          text.addEventListener('input', function (){
            useCount.innerText=text.value.length
          })
          // let sum=0
          // let timeId=setInterval(createLi,50)
          // 发布事件
          send.addEventListener('click',function (){
            // 判断是否有内容
            if (text.value=='') {
              alert('内容为空不可发布')
              return false
            }
            createLi()
            useCount.innerText=0
            text.value=''
          })
          // 封装li创建节点函数
          function createLi() {
            // 获取随机数
            let getRan=Math.round(Math.random()*(dataArr.length-1))
            // 重新获取lis数组
            let lis=document.querySelectorAll("li")
            // 创建li标签
            let li=document.createElement('li')
            // 头像,用户名,发布时间的盒子
            let info=document.createElement('div')
            info.classList.add('info')
            // 头像
            let img=document.createElement('img')
            img.classList.add('userpic')
            img.src=dataArr[getRan].imgSrc
            // 创建用户名
            let username=document.createElement('span')
            username.classList.add('username')
            username.innerText=dataArr[getRan].uname
            // 发布时间标签
            let send_time=document.createElement('p')
            send_time.classList.add('send-time')
            // 存放时间的变量
            let nowTime=getTime()
            send_time.innerText=`发布于 ${nowTime}`
            // 发布内容
            let content=document.createElement('div')
            content.classList.add('content')
            content.innerText=text.value
            // 删除按钮
            let the_del=document.createElement('span')
            the_del.classList.add('the_del')
            the_del.innerText='×'
            // 合并所有节点
            info.append(img,username,send_time)
            li.append(info,content,the_del)
            ul.insertBefore(li,lis[0])
            // 同时注册关闭功能
            the_del.addEventListener('click',function (){
              this.parentNode.remove()
            })
          }
          
          // 获取时间
          function getTime() {
            // 获取时间所有代码封装
            let date=new Date()
            let year=date.getFullYear()
            let month=date.getMonth()+1
            let day=date.getDate()
            let hour=date.getHours()
            let min=date.getMinutes()
            let sec=date.getSeconds()
            return `${year}-${month}-${day} ${hour}:${min}:${sec}`
          }
        
        
        </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>
              <!-- <li>
                <div class="info">
                  <img class="userpic" src="./images/9.5/06.jpg" />
                  <span class="username">张良</span>
                  <p class="send-time">发布于 2022-4-7 15:12:23</p>
                </div>
                <div class="content">sdfdf</div>
                <span class="the_del">X</span>
              </li> -->
            </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 text=document.querySelector("textarea")
          let useCount=document.querySelector(".useCount")
          // 获取发布按钮
          let send=document.querySelector("#send")
          // 获取ul元素
          let ul=document.querySelector("ul")
          // 文本框事件
          text.addEventListener('input', function (){
            useCount.innerText=text.value.length
          })
          // 发布事件
          send.addEventListener('click',function (){
            // 判断是否有内容
            if (text.value=='') {
              alert('内容为空不可发布')
              return false
            }
            let user=getUser()
            let liHtml=`
            <li>
                <div class="info">
                  <img class="userpic" src=${user.imgSrc} />
                  <span class="username">${user.uname}</span>
                  <p class="send-time">发布于 ${getTime()}</p>
                </div>
                <div class="content">${text.value}</div>
                <span class="the_del">×</span>
              </li>
            `
            ul.innerHTML+=liHtml
            useCount.innerText=0
            text.value=''
          })
          // 封装获取随机用户对象函数
          function getUser() {
            let index=Math.round(Math.random()*(dataArr.length-1))
            return dataArr[index]
          }
          // 获取时间
          function getTime() {
            // 获取时间所有代码封装
            let date=new Date()
            let year=date.getFullYear()
            let month=date.getMonth()+1
            let day=date.getDate()
            let hour=date.getHours()
            let min=date.getMinutes()
            let sec=date.getSeconds()
            return `${year}-${month}-${day} ${hour}:${min}:${sec}`
          }
        
        
        </script>
      </body>
    </html>