JavaScript web API完结篇---多案例

BOM

window对象 ==>包含docment

Browser Object Model


定时器--延时函数

之前学的是间歇函数

让代码延迟执行 ++仅执行一次++

setTimeout(回调函数,等待毫秒数)

消除 clearTimeout(timer) ==> 用于递归时需要进行去除

JS执行机制

单线程 ==> 一个任务结束,才会执行下一个任务

++导致渲染慢++

如何解决?

Web Worker标准 == 允许JavaScript脚本创建多个线程

因此分出了同步和异步

同步 程序的执行顺序和任务的排列顺序一样
异步 当一件事花费很长时间,同时还可以处理其他事情
同步任务 立马就能执行,都在主线程上执行,形成一个执行栈
异步任务 普通事件,资源加载,定时器等等,添加到任务队列中

!IMPORTANT

  • 先执行执行栈【相当于主车道】中的同步任务
  • 异步任务放入任务队列中【应急车道】
  • 一旦执行栈中的所有同步任务执行完毕,系统会按次序读取任务队列中的异步任务==> 结束等待状态,进入执行栈,执行

事件循环

进行多线程处理的是,浏览器宿主环境而不是JavaScript,


location 对象

拆分并保存了URL的各个部分

常用属性

href 赋值则会跳转到网址,可配合定时器
search 拿地址中'?'后面的信息(表单提交的数据等)
hash '#'后面的值

补充方法:

​ reload(布尔值) 若为true,则可以强制刷新

判断用户使用设备 ==> 跳转到适配页面

history 对象

管理历史记录,前进后退历史页面

++相当于浏览器中的前进后退的按钮++

back() 后踢一个页面
forward() 前进一个页面
go(参数) 通过参数判断前进后退到哪里

本地存储

本地存储数据,读取方便,刷新页面不会丢失

localStorage 永久存储在本地

  • 增 setItem(key,value)
  • 删 removeItem(key)
  • 改 setItem(key,value)
  • 获取 getItem(key)

路径:

检查 ==> Application ==> Storage ==> local ...

sessionStorage

不同:生命周期为关闭浏览器窗口

若需要存储复杂数据

转换为JSON字符串存储,转换会复杂数据类型获取

JSON.stringify(复杂数据类型) JSON.parse(key)


综合案例

学生统计表

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>学生就业统计表</title>
  <link rel="stylesheet" href="./iconfont/iconfont.css">
  <link rel="stylesheet" href="css/index.css" />
</head>

<body>
  <h1>学生就业统计表</h1>
  <form class="info" autocomplete="off">
    <input type="text" class="uname" name="uname" placeholder="姓名" />
    <input type="text" class="age" name="age" placeholder="年龄" />
    <input type="text" class="salary" name="salary" placeholder="薪资" />
    <select name="gender" class="gender">
      <option value="男">男</option>
      <option value="女">女</option>
    </select>
    <select name="city" class="city">
      <option value="北京">北京</option>
      <option value="上海">上海</option>
      <option value="广州">广州</option>
      <option value="深圳">深圳</option>
      <option value="曹县">曹县</option>
    </select>
    <button class="add">
      <i class="iconfont icon-tianjia"></i>添加
    </button>
  </form>

  <div class="title">共有数据<span>0</span>条</div>
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>姓名</th>
        <th>年龄</th>
        <th>性别</th>
        <th>薪资</th>
        <th>就业城市</th>
        <th>录入时间</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      <!-- 
      <tr>
        <td>1</td>
        <td>迪丽热巴</td>
        <td>23</td>
        <td>女</td>
        <td>12000</td>
        <td>北京</td>
        <td>2099/9/9 08:08:08</td>
        <td>
          <a href="javascript:">
            <i class="iconfont icon-shanchu"></i>
            删除
          </a>
        </td>
      </tr> -->
    </tbody>
  </table>
  <script>
    //  const obj = {
    // stuId: arr.length + 1,
    // uname: uname.value,
    // age: 22,
    // salary: salary.value,
    // gender: gender.value,
    // city: city.value,
    // time: new Date().toLocaleString(),
    //     }
    //获取对象
    const tbody = document.querySelector('tbody')
    const info = document.querySelector('.info')
    const add = document.querySelector('.add')
    const uname = document.querySelector('.uname')
    const age = document.querySelector('.age')
    const salary = document.querySelector('.salary')
    const gender = document.querySelector('.gender')
    const city = document.querySelector('.city')
    const howmany = document.querySelector('.title span')

    const initData = []
    // localStorage.setItem('data', JSON.stringify(initData))
    const arr = JSON.parse(localStorage.getItem('data'))
    render()
    //渲染业务
    function render() {
      //从本地数据中读取数组
      //更改为tr的格式
      const newArr = arr.map(function (ele, index) {
        return `
           <td>${ele.stuId}</td>
            <td>${ele.uname}</td>
            <td>${ele.age}</td>
            <td>${ele.gender}</td>
            <td>${ele.salary}</td>
            <td>${ele.city}</td>
            <td>${ele.time}</td>
            <td>
              <a href="javascript:" data-id="${index}">
                <i class="iconfont icon-shanchu"></i>
                删除
              </a>
            </td>
          </tr>
        `
      })
      console.log(newArr);

      //转化为字符串形式并存储到tbody的innerHTMl中
      tbody.innerHTML = newArr.join('')
      //渲染一共有几条数据
      howmany.innerHTML = arr.length
    }

    //新增业务
    function addMan() {
      //点击添加按钮
      //1.阻止表单默认提交行为
      info.addEventListener('submit', function (e) {
        e.preventDefault()
      })
      //2.判断表单中是否有内容空了,空了则返回提示信息
      if (!uname.value || !age.value || !salary.value) {
        return alert('输入内容不能为空')
      }
      //3.将表单的数据写道对象中
      //4.将对象追加到arr数组中去
      arr.push({
        stuId: arr.length + 1,
        uname: uname.value,
        age: 22,
        salary: salary.value,
        gender: gender.value,
        city: city.value,
        time: new Date().toLocaleString()
      })
      //4.1将arr存储到本地中
      localStorage.setItem('data', JSON.stringify(arr))
      //5.重新渲染页面
      render()
      //6.重置表单
      info.reset()
    }

    add.addEventListener('click', function () {
      addMan()
    })

    //删除业务
    //1.点击删除按钮 tbody 利用事件委托
    tbody.addEventListener('click', function (e) {
      //2.判断是否为a
      if (e.target.tagName === 'A') {
        //3.弹窗,询问是否删除
        // let input = +(prompt('是否删除,删除选1,不删除选0'))
        if (confirm('您是否要删除这条学生数据')) {
          //4.若删除,获取对应对象的dataset值
          //5.通过对应的id值来索引下标,删除arr中的对应元素
          arr.splice(+(e.target.dataset.id), 1)
          //5.1将本地存储数据更新
          localStorage.setItem('data', JSON.stringify(arr))
          //6.重新渲染页面
          render()
        }

      }


    })

  </script>
</body>

</html>

可实现

  • 渲染页面
  • 新增数据
  • 删除数据
  • 刷新页面不会消失数据,依旧有以前的数据

正则表达式(对象)

用于匹配字符串中字符组合的模式

use:用来查找,替换那些符合正则表达式的文本 ==> 匹配,替换,提取

语法

  1. 定义规则 /....../ ==> 字面量
  2. 查找

方法

test(字符串) 返回布尔值
exec(字符串) 返回数组或null

exec()返回的数组中包含的是匹配正则表达式的字符串的相关信息

元字符

具有特殊含义的字符

  1. 边界符 ^---开头 $---结尾 两个一起使用则为精准匹配
  2. 量词
  3. 字符类


修饰符

++语法位置++

/...../修饰符

i 忽略字母大小写
g 匹配所有结果

案例

用户验证案例

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>
        span {
            display: inline-block;
            width: 250px;
            height: 30px;
            vertical-align: middle;
            line-height: 30px;
            padding-left: 15px;
        }

        .error {
            color: red;
            background: url(./images/error1.png) no-repeat left center;
        }

        .right {
            color: green;
            background: url(./images/right.png) no-repeat left center;
        }
    </style>
</head>

<body>
    <input type="text">
    <span></span>
    <script>
        //获取对象
        const input = document.querySelector('input')
        const span = document.querySelector('span')

        //书写正则表达式的规则
        const rule = /^[a-zA-Z0-9-_]{6,16}$/
        //绑定事件
        input.addEventListener('blur', function () {
            //判断是否符合正则表达式规则
            if (rule.test(this.value)) {
                span.className = 'right'
                // console.log('right');
                span.innerHTML = '输入正确'

            } else {
                span.className = 'error'
                // console.log('wrong');
                span.innerHTML = '请输入6-16位由英文字母,数字,下划线的字符串'
            }
        })

    </script>
</body>

</html>

综合案例:

页面注册

JavaScript 复制代码
//获取所有对象
    const code = document.querySelector('.code')


    //发送验证码模块
    //获取对象
    //绑定点击事件
    let flag = true //控制在倒计时内无法再次点击发送验证码 节流阀
    code.addEventListener('click', function () {
      if (flag) {
        flag = false
        let num = 5
        code.innerHTML = '5秒后重新获取'
        let stop = setInterval(function () {
          num--
          code.innerHTML = `${num}秒后重新获取`
          if (num === 0) {
            code.innerHTML = `重新获取`
            clearInterval(stop)
            //到时间了,可以使节流阀flag打开了
            flag = true
          }
        }, 1000)
      }
    })

    //验证输入内容是否符合模块
    //1.用户名模块
    const name = document.querySelector('[name=username]')

    //1.1绑定事件
    name.addEventListener('change', verifyName)
    //1.2封装函数
    function verifyName() {
      // console.log(11);
      const tip = name.nextElementSibling
      //设定正则表达式
      const ruleName = /^[a-zA-Z0-9-_]{6,10}$/
      if (!ruleName.test(name.value)) {
        tip.innerHTML = '输入有误,请输入6-10位'
        return false
      }
      tip.innerHTML = ''
      return true
    }





    //2.手机号模块
    const phone = document.querySelector('[name=phone]')

    //1.1绑定事件
    phone.addEventListener('change', verifyPhone)
    //1.2封装函数
    function verifyPhone() {
      // console.log(11);
      const tip = phone.nextElementSibling
      //设定正则表达式
      const rulePhone = /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/
      if (!rulePhone.test(phone.value)) {
        tip.innerHTML = '输入有误,请输入11位手机号码'
        return false
      }
      tip.innerHTML = ''
      return true
    }




    //3.密码模块
    const password = document.querySelector('[name=password]')

    //1.1绑定事件
    password.addEventListener('change', verifypassword)
    //1.2封装函数
    function verifypassword() {
      // console.log(11);
      const tip = password.nextElementSibling
      //设定正则表达式
      const rulepassword = /^[a-zA-Z0-9-_]{6,20}$/
      if (!rulepassword.test(password.value)) {
        tip.innerHTML = '输入有误,请输入6-20位字母数字下划线密码'
        return false
      }
      tip.innerHTML = ''
      return true
    }


    //4.验证码模块
    const Code = document.querySelector('[name=code]')
    //1.1绑定事件
    Code.addEventListener('change', verifyCode)
    //1.2封装函数
    function verifyCode() {
      // console.log(11);
      const tip = Code.nextElementSibling
      //设定正则表达式
      const ruleCode = /^\d{6}$/
      if (!ruleCode.test(Code.value)) {
        tip.innerHTML = '输入有误,请输入6位数字'
        return false
      }
      tip.innerHTML = ''
      return true
    }

    //5.再次密码验证模块
    const confirm = document.querySelector('[name=confirm]')
    //1.1绑定事件
    confirm.addEventListener('change', verifyconfirm)
    //1.2封装函数
    function verifyconfirm() {
      // console.log(11);
      const tip = confirm.nextElementSibling
      //设定正则表达式
      const ruleconfirm = /^\d{6}$/
      if (!(confirm.value === password.value)) {
        tip.innerHTML = '与上述密码不一致'
        return false
      }
      tip.innerHTML = ''
      return true
    }


    //6.协议模块
    //获取对象
    const agree = document.querySelector('.icon-queren')
    //绑定点击事件

    agree.addEventListener('click', function () {
      agree.classList.toggle('icon-queren2')
    })

    //7.全部提交
    //获取表单对象
    const form = document.querySelector('form')
    //添加提交事件监听器
    form.addEventListener('submit', function (e) {
      //判断是否同意协议
      if (!agree.classList.contains('icon-queren2')) {
        alert('请勾选同意协议')
        //阻止表单默认行为
        e.preventDefault()

      }
      //依次判断其他模块是否输入正确内容
      if (!verifyName()) e.preventDefault()
      if (!verifyconfirm()) e.preventDefault()
      if (!verifyCode()) e.preventDefault()
      if (!verifypassword()) e.preventDefault()
      if (!verifyPhone()) e.preventDefault()
    })

补充知识点:

  • input的change事件 ==> 当内容发生变化,且失去焦点,事件触发
  • classList有新方法contains('类名') 返回布尔值

登录页面

JavaScript 复制代码
 //1.tab栏切换
    //获取对象 --  事件委托
    const tab_nav = document.querySelector('.tab-nav')
    const panel = document.querySelectorAll('.tab-pane')
    //绑定事件
    tab_nav.addEventListener('click', function (e) {
      if (e.target.tagName === 'A') {
        //取消之前的active
        tab_nav.querySelector('.active').classList.remove('active')
        //增加后来的active
        e.target.classList.add('active')
      }
      //更换对应盒子
      //先全部去除
      for (let i = 0; i < panel.length; i++) {
        panel[i].style.display = 'none'
      }
      //显示对应需要的盒子
      panel[e.target.dataset.id].style.display = 'block'
    })

    //点击提交事件
    const agree = document.querySelector('[name=agree]')
    const form = document.querySelector('form')
    const username = document.querySelector('[name=username]')
    const password = document.querySelector('[name=password]')
    //绑定提交事件
    form.addEventListener('submit', function (e) {
      //阻止提交
      e.preventDefault()
      //判断是否有同意协议
      if (!agree.checked) {
        alert('请勾选协议')
      }
      //将数据存储到本地存储中去
      localStorage.setItem('xtx_name', username.value)
      localStorage.setItem('xtx_pwd', password.value)
      //跳转页面
      location.href = 'http://127.0.0.1:5500/webAPI/%E5%85%83%E5%AD%97%E7%AC%A6%E6%A1%88%E4%BE%8B/%E7%BB%BC%E5%90%88%E6%A1%88%E4%BE%8B%E7%B4%A0%E6%9D%90/index.html'
    })

首页页面

JavaScript 复制代码
//获取对象
    const li1 = document.querySelector('.xtx_navs li:first-child')
    const li2 = li1.nextElementSibling

    //封装render函数
    function render() {
      //获取本地数据
      const uname = localStorage.getItem('xtx_name')
      //判断是否有用户名数据
      if (uname) {
        li1.innerHTML = ` <a href="javascript:;">${uname}</a>`
        li2.innerHTML = ` <a href="javascript:;">退出登录</a>`
      } else {
        li1.innerHTML = `<a href="./login.html">请先登录</a>`
        li2.innerHTML = ` <a href="./register.html">免费注册</a>`
      }
    }
    //跳转页面后先进行一次渲染
    render()
    //绑定事件
    li2.addEventListener('click', function () {
      //删除本地数据
      localStorage.removeItem('xtx_name')

      //重新渲染
      render()
    })
相关推荐
deli0071 小时前
32K 上下文塞满后,AI 最先忘掉什么?120 轮对话实测
前端
deli0072 小时前
手机拍灯为什么有一条条黑纹?PWM 240Hz 实测
前端
wangruofeng7 小时前
AI Models 1.1.0 发布,查大模型价格、对比模型和找 API 地址
前端·aigc·ai编程
wangruofeng7 小时前
给前端开发者的 100 个设计参考网站
前端·设计
starzy19909 小时前
深入理解Scala隐式类:扩展方法机制
开发语言·人工智能·scala
M--Y9 小时前
LangGraph 工作流模式
开发语言·javascript·python·langchain·大模型·llm·langgraph
星栈10 小时前
视频即代码,Remotion 能做什么、不能做什么
前端·音视频开发
广州华水科技10 小时前
单北斗GNSS位移监测系统的应用与技术解析
前端
用户479492835691510 小时前
从一句话或代码仓到可交互 HTML:开源 Agent 画图技能 Archify v3.2 实测与选型边界
前端·后端·面试
吴可可12310 小时前
WScript Shell操作注册表详解
开发语言