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()
    })
相关推荐
学不会•24 分钟前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
EasyNTS1 小时前
H.264/H.265播放器EasyPlayer.js视频流媒体播放器关于websocket1006的异常断连
javascript·h.265·h.264
Theodore_10221 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
活宝小娜3 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点3 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow3 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o3 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
----云烟----3 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024063 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
开心工作室_kaic4 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端