webApi第七天

79 阅读5分钟

webApi第7天

本地存储

本地存储特性

随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案。 1、数据存储在用户浏览器中 2、设置、读取方便、甚至页面刷新不丢失数据 3、容量较大,sessionStorage和localStorage约 5M 左右

localStorage

1、生命周期永久生效,除非手动删除 否则关闭页面也会存在 2、可以多窗口(页面)共享(同一浏览器可以共享)

  1. 以键值对的形式存储使用

1650977738752.png

存储复杂数据类型存储 本地只能存储字符串,无法存储复杂数据类型.需要将复杂数据类型转换成JSON字符串,在存储到本地 JSON.stringify(复杂数据类型) 将复杂数据转换成JSON字符串 存储 本地存储中 JSON.parse(JSON字符串) 将JSON字符串转换成对象 取出 时候使用

页面背景颜色--本地存储案例

<body>
    
    <input type="color">

    <script>
        //body背景颜色等于本地存储中的颜色
        document.body.style.backgroundColor = localStorage.getItem('color')

        //获取colorinput标签  并绑定改变事件
        let colorDom = document.querySelector('input')
        colorDom.addEventListener('change',function () {
            // console.log(colorDom.value  );    
            //设置背景颜色为colorinput的颜色 
            document.body.style.backgroundColor = colorDom.value

            //设置input的颜色值到本地村粗中
            localStorage.setItem('color',`${colorDom.value}`)  
        })
        
    </script>
</body>

学生就业薪资+本地存储-案例

<!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>08-综合案例-模版</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      a {
        text-decoration: none;
        color: #721c24;
      }
      h1 {
        text-align: center;
        color: #333;
        margin: 20px 0;
      }
      table {
        margin: 0 auto;
        width: 800px;
        border-collapse: collapse;
        color: #004085;
      }
      th {
        padding: 10px;
        background: #cfe5ff;

        font-size: 20px;
        font-weight: 400;
      }
      td,
      th {
        border: 1px solid #b8daff;
      }
      td {
        padding: 10px;
        color: #666;
        text-align: center;
        font-size: 16px;
      }
      tbody tr {
        background: #fff;
      }
      tbody tr:hover {
        background: #e1ecf8;
      }
      .info {
        width: 900px;
        margin: 50px auto;
        text-align: center;
      }
      .info input {
        width: 80px;
        height: 25px;
        outline: none;
        border-radius: 5px;
        border: 1px solid #b8daff;
        padding-left: 5px;
      }
      .info button {
        width: 60px;
        height: 25px;
        background-color: #004085;
        outline: none;
        border: 0;
        color: #fff;
        cursor: pointer;
        border-radius: 5px;
      }
      .info .age {
        width: 50px;
      }
    </style>
  </head>

  <body>
    <h1>新增学员</h1>
    <div class="info">
      姓名:<input type="text" class="uname" /> 年龄:<input
        type="text"
        class="age"
      />
      性别:
      <select name="gender" id="" class="gender">
        <option value="男"></option>
        <option value="女"></option>
      </select>
      薪资:<input type="text" class="salary" /> 就业城市:<select
        name="city"
        id=""
        class="city"
      >
        <option value="北京">北京</option>
        <option value="上海">上海</option>
        <option value="广州">广州</option>
        <option value="深圳">深圳</option>
        <option value="曹县">曹县</option>
      </select>
      <button class="add">录入</button>
    </div>

    <h1>就业榜</h1>
    <table>
      <thead>
        <tr>
          <th>学号</th>
          <th>姓名</th>
          <th>年龄</th>
          <th>性别</th>
          <th>薪资</th>
          <th>就业城市</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <!-- <tr>
          <td>1</td>
          <td>这是名称</td>
          <td>这是年龄</td>
          <td>这是性别</td>
          <td>这是工资</td>
          <td>这是所在城市</td>
          <td>
            <a href="javascript:" class="del">删除</a>
          </td>
        </tr> -->
      </tbody>
    </table>
    <script>
      // 1.1 定义数组 负责存放表格要显示的数据
      // 获取本地存储中的数组(字符串格式)  转成 数组格式

      // 第一次打开页面的时候 ,本地存储里面会有数据吗

      const newArr = localStorage.getItem('arr')
      let arr = [];
      if (newArr){
          arr = JSON.parse(newArr)
      }else {arr = arr}
      
      const tbody = document.querySelector('tbody');
      // 2  给 录入绑定点击事件
      const add = document.querySelector('.add');
      const uname = document.querySelector('.uname');
      const age = document.querySelector('.age');
      const gender = document.querySelector('.gender');
      const salary = document.querySelector('.salary');
      const city = document.querySelector('.city');

      // 1.2 根据数组渲染页面
      renderTableByArr();

      // 2  按钮绑定点击事件
      add.addEventListener('click', function () {
        // 2.1 创建一个新的对象 把表单数据都合并到对象中
        const data = {
          // 学号
          id: Date.now(),
          // 姓名
          uname: uname.value,
          // 年龄
          age: age.value,
          // 性别
          gender: gender.value,
          // 薪资
          salary: salary.value,
          // 就业城市
          city: city.value,
        };

        // 老师打了一个 断点 来验证 上面的代码 没有写错
        // 2.2 给数组插入新的元素
        arr.push(data);

        //数组转字符串
        const strArr = JSON.stringify(arr)
        //本地存储
        localStorage.setItem('arr',strArr)

        

        

        // 2.3 数组发生改变  重新调用渲染页面的函数
        renderTableByArr();

        // 2.4 表单数据清空
        uname.value = '';
        age.value = '';
        gender.value = '男';
        salary.value = '';
        city.value = '北京';
      });

      // 3 tbody绑定点击事件,同时判断被点击的是不是 del 删除标签
      tbody.addEventListener('click', function (event) {
        // 3.1 判断当前点击的是不是a标签
        if (event.target.nodeName === 'A') {
          // <a data-index="2" href="javascript:" class="del">删除</a>

          // 获取到a标签 上存放的 index
          // event.target =  a标签的dom元素
          // console.dir(event.target.dataset.index)
          const index = event.target.dataset.index;

          // 3.3 执行数组删除元素
          arr.splice(index, 1);

        //数组转字符串
        const strArr = JSON.stringify(arr)

        //本地存储
        localStorage.setItem('arr',strArr)

          
          

          // 3.4 调用根据数组渲染页面的函数
          renderTableByArr();
        }
      });
      // 根据数组渲染表格
      function renderTableByArr() {
        let html = ``;
        for (let index = 0; index < arr.length; index++) {
          html += `
         <tr>
          <td>${arr[index].id}</td>
          <td>${arr[index].uname}</td>
          <td>${arr[index].age}</td>
          <td>${arr[index].gender}</td>
          <td>${arr[index].salary}</td>
          <td>${arr[index].city}</td>
          <td>
            <a data-index="${index}" href="javascript:" class="del">删除</a>
          </td>
        </tr>
         `;
        }

        // 把生成的tr插入到 tbody中
        tbody.innerHTML = html;
      }
    </script>
  </body>
</html>

sessionStorage

  1. sessionStorage 本地存储的用法和 localStorage 是一样的。
  2. 区别在于:只是他存储的数据 在关闭页面后 ,数据就会丢失。localStorage 会一直保存着,除非手动删除。
<body>
    <script>
        sessionStorage.setItem('abc',123)
        sessionStorage.getItem('abc')

        /* 
      本地存储的技术 sessionStorage  会话(打开页面到关闭页面之间过程 一次会话  ajax node)存储
      登录的时候 
      它的用法和 localStorage 用法一样 
      区别只有一个 
      sessionStorage 关闭页面后 数据就丢失 
      localStorage 除非是用户主动删除 否则一直存在 直到天荒地老
       */

      //  存数据
      // sessionStorage.setItem("ss",123);
      //  取数据
      // console.log(sessionStorage.getItem("ss"));
      // 删除一个
      // sessionStorage.removeItem("ss")
      // 清空
      // sessionStorage.clear();
    </script>
</body>

元素属性

固有属性

1.标签的固有属性 比如a标签的href属性,img标签的src属性 各标签的id属性等 获取和设置比较方便 可以直接使用 . 语法

<body>
    <a data-index="0" id="nav" href="http://www.baidu.com" hello="no" aa="bb" >跳转</a >

    <script>
      const a = document.querySelector('a');
      // 获取固有属性
      console.log(a.href);
      console.log(a.id);

      // 直接修改
      a.href="http://www.qq.com";
      a.id="top";
    </script>  
  </body>
自定义属性
  • 自己给标签创建的属性名,不能通过 . 语法来获取和设置。

  • 获取 getAttribute("属性名")

  • 设置/添加、修改 setAttribute("属性名",修改的内容)

  • 删除属性 removeAttribute ("要删除的属性名")

  <body>
    <a data-index="0" id="nav" href="#" hello="no" aa="bb" >跳转</a >

    <script>
      const a = document.querySelector('a');
     
      // 自定义属性 不能直接通过点语法来获取和设置
      // 获取 getAttribute("属性名")
      console.log( a.getAttribute("hello") );
      console.log( a.getAttribute("aa") );

      // 设置/添加、修改 setAttribute(key,value)
      //标签已有该属性名为修改   没有为添加
      a.setAttribute("hell0","123");
      a.setAttribute("hell","123");
        
      // 删除属性 removeAttribute(key)
      a.removeAttribute("hello");
    </script>  
  </body>
html5建议的自定义属性
  • 属性: data-xxx 开头;

  • 获取: a.dataset.xxx;

  • 设置: 元素.dataset.xxx = 自定义的取值;

<body>
    <a data-index="0" id="nav" href="http://www.baidu.com">跳转</a >

    <script>
          // 自定义属性 -> h5建议的 自定义属性
          // 属性的时候 data-xxx 开头
          // 获取的时候  a.dataset.xxx
          // 设置  a.dataset.index = 3;

          // console.log(a.dataset.index);
          // a.dataset.index = 3;
    </script>
  </body>

小结

标签的属性 有两种分为

  • 固有属性 比如 id href src 点语法的方式获取和设置 方便

  • 自定义属性

​ 1. 随意自己命名

          <a  abc="123" >  

​ 获取 getAttribute(key) 设置 setAttribute(key,value) 删除 removeAttribute(key)

​ 2 . h5建议 data- xxx

          <a  data-abc="123" >  

​ 获取(a.dataset.abc) 设置(a.dataset.abc=456);

  • 最强大是 (getAttribute) setAttribute removeAttribute

​ 上述的这个方式,可以获取到任意的属性(固有属性和h5建议的自定义属性)

            跳转

高阶函数

一个函数a 可以把另一个函数b 当成参数来接收处理,或者返回另外一个新的函数c。

如果将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数 简单理解: 当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数

  • 高阶函数可以被简单理解为函数的高级应用,JavaScript 中函数可以被当成【值】来对待,基于这个特性实现函数的高级应用。
  • 【值】就是 JavaScript 中的数据,如数值、字符串、布尔、对象等。
  <script>
  
     function f1(callback) {
         callback();
       }
     function f2() {
        console.log("我就是高阶函数");
      }   
       f1(f2);// f2 当成是一个普通的参数来使用(形参来使用)   
        
       setInterval(f2,1000);// 把f2 当成是一个普通参数  传递给别人使用
        
          const btn=document.querySelector("button");
        btn.addEventListener("click",f2);// f2 也是高阶函数

       function getIndex() {
         let index=0;
         return function () {
            index++;
             console.log(index);
         }
       }
       const ff=getIndex();
       ff();
        
   </script>

作用:后期 react阶段 会用到。 暂时做了解 后期会再讲解!!!

重绘和回流(重排)

1651041342228.png

  • 回流(重排) 当 Render Tree 中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过程称为 回流。

  • 重绘 由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、outline等), 称为重绘。

  • 重绘不一定引起回流,而回流一定会引起重绘。

  • 会导致回流(重排)的操作: 1.页面的首次刷新 2.浏览器的窗口大小发生改变 3.元素的大小或位置发生改变 4.改变字体的大小 5.内容的变化(如:input框的输入,图片的大小) 6.激活css伪类 (如::hover) 7.脚本操作DOM(添加或者删除可见的DOM元素)

  • 简单理解影响到布局了,就会有回流

定义:出现重绘,不会重排;出现重排, 一定会出现重绘。

时间绑定-取消绑定

removeEventListener 可以取消元素的绑定事件。

<style>
        body {
            height: 100vw;
        }
    </style>
</head>
<body>
    <script>
        function text() {
            console.log('gugu');
        }

        function text2() {
            console.log(text);
        }
        //给body添加绑定事件
        document.body.addEventListener('click',text)
        //绑定多个同名事件
        document.body.addEventListener('click',text2)

        setInterval(function () {
            //设置延时器 一定时间后取消该点击事件
            document.body.removeEventListener('click',text)
        },5000)

         /* 
        1 addEventListener 可以绑定多个同名事件
        2 removeEventListener 可以取消对应的事件类型和事件处理函数
        3 无法取消 addEventListener 事件 对应的匿名函数 
        */
        
    </script>
</body>

注: 匿名函数无法取消绑定,应为对应的函数名不知道是什么,多以取消不了。

事件流动

时间流动实际上有三个阶段

1.最重要的 冒泡阶段

2.捕获阶段

3.目标阶段 (了解)-- 点击了最底层的标签 处在目标阶段。

字符串方法

字符串转换方法
转大写toUpperCase()
转小写toLowerCase()
转数组str.split('') 括号内填写以"什么"为分割符
拼接字符串concat --很少用 直接用+拼接
   <script>
        // 我们在实际开发过程中,有很多需求要针对字符串做处理
        // js 帮我们封装了很多大量和实用 字符串方法
        // 先介绍一些

        /* let str = 'abcdefg'
        //转大写
        console.log(str.toUpperCase()); */

        /* let str = 'ABCDEFG'
        //转小写
        console.log(str.toLowerCase()); */

        let str = 'abcdefg'
        // 转数组
        console.log(str.split('')); //=> ["a","b","c","d","e","f","g"]

        let str1 = 'a-b-c-d-e-f-g'
        console.log(str1.split('-'));//=> ["a","b","c","d","e","f","g"]
         /*
       1 转大写  toUpperCase()

       2 转小写 toLowerCase()

       3 转数组 str.split('') 按照什么来分割你的字符串变成数组
       */
    </script>

数组方法

数组转换方法
数组转字符串join('')
数组拼接concat--- arr1.concat(arr2) 可拼接多个数组
<script>
        const arr = ['a','b','c','d']
        //数组转字符串  join('')
        console.log(arr.join(''));  //转后无分隔
        console.log(arr.join('-'));  //转后-分隔

  
        //两个数组合并成一个数组  要合并的数组1.concat(要合并的数组2) --转换后数组1在前--
        //可以拼接多个数组
        const arr1 = [1,2,3,4]
        const arr2 = ['a','b','c','d']
        const arr3 = ['1','2','3','4']
        console.log(arr2.concat(arr1)); //['a','b','c','d',1,2,3,4]
        console.log(arr2.concat(arr1).concat(arr3)); // => ['a','b','c','d',1,2,3,4,'1', '2', '3', '4']
    </script>

正则表达式

  • 正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象
  • 通常用来查找、替换那些符合正则表达式的文本,许多语言都支持正则表达式。
  • 正则表达式在 JavaScript中的使用场景:
    1. 例如验证表单:用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配) 2.比如用户名: /^[a-z0-9_-]{3,16}$/ 3.过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等 。

1651049632187.png

例:

<script>
        /* 
       正则的作用 寻找字符串  检测 这个字符串这有没有我想要的文字
      */

        const text = '学习正则表达式概念及语法,编写简单的正则表达式实现字符的查找或检测。'

        //定义规则
        const reg = /正则/
        const reg1 = /六一/
        /*  const re = reg.test(text)
         console.log(re); */

        // 规则和字符串 匹配  test  // 规则名.test(要检测的数据)
        //有的话 返回true 没有返回 false 
        console.log(reg.test(text)); // => true
        console.log(reg1.test(text)); // => false
    </script>

元字符

  • 普通字符: 大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。 也就是说普通字符只能够匹配字符串中与它们相同的字符。
  • 元字符(特殊字符) 是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。 比如,规定用户只能输入英文26个英文字母,普通字符的话 abcdefghijklm….. 但是换成元字符写法: [a-z]
  • 参考文档: MDN:developer.mozilla.org/zh-CN/docs/… 正则测试工具: tool.oschina.net/regex
1.边界符

表示位置,开头和结尾,必须用什么开头,用什么结尾

正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符

1651052152374.png

正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符

如果 ^ 和 $ 在一起,表示必须是精确匹配。

例1:

1651054253018.png

例2:

<script>
      const text = '大聪明'

      //边界符  /开头^  结尾$/
      
      //如果只加了^开头,那只要最前面和符号里一样就行,后面有多少字都会返回 true
      const reg1 = /^大聪明/
      const reg2 = /^大/
      console.log(reg1.test(text)); // =>true
      console.log(reg2.test(text)); // =>true

      //如果只加了$结尾,那只要最后面的字和符号里一样就行,前面面有多少字都会返回true
      const reg3 = /明$/
      const reg4 = /聪明$/
      const reg5 = /大聪明$/
      console.log(reg3.test(text)); // =>true
      console.log(reg4.test(text)); // =>true
      console.log(reg5.test(text)); // =>true

      //边界^$,那里面的文字必须和边界符一模一样,否则返回false,多一个字都不行
      const reg6 = /^大明$/
      const reg7 = /^大聪明$/
      console.log(reg6.test(text)); // =>false
      console.log(reg7.test(text)); // =>true
    </script>
2.量词

量词用来 设定某个模式出现的次数

1651054344853.png

注意: 逗号左右两侧千万不要出现空格

<script>
      // const str="路飞";
      // const reg=/路飞/;
      // console.log(reg.test(str));

      //  *  表示 放在它前面那一个字符 可以出现0次或者多次
      // /^路*$/   => "",  路,路路,路路路
      // console.log(/^千*$/.test('')); // true
      // console.log(/^千*$/.test('千')); // true
      // console.log(/^千*$/.test('千千')); // true
      // console.log(/^千*$/.test('千千千')); // true

      // + 表示 放在它前面那一个字符 可以出现1次或者多次
      // console.log(/^千+$/.test(''));
      // console.log(/^千+$/.test('千'));
      // console.log(/^千+$/.test('千千'));
      // console.log(/^千+$/.test('千千千'));

      // ? 表示出现0次或者1次
      // console.log(/^千?$/.test(''));// true
      // console.log(/^千?$/.test('千')); // true
      // console.log(/^千?$/.test('千千')); // false
      // console.log(/^千?$/.test('千千千')); // false

      // {n} 放在它前面的那一个字符 出现n次
      // console.log(/^千{2}$/.test('')); // false
      // console.log(/^千{2}$/.test('千')); // false
      // console.log(/^千{2}$/.test('千千')); // true
      // console.log(/^千{2}$/.test('千千千')); // false

      // {n,} 放在它前面的字符 最少出现n次
      // console.log(/^千{2,}$/.test('')); // true
      // console.log(/^千{2,}$/.test('千')); // true
      // console.log(/^千{2,}$/.test('千千'));// true
      // console.log(/^千{2,}$/.test('千千千')); // true

      // {n,m} 放在它前面的字符 最少出现n次,最大是m次
      console.log(/^千{0,2}$/.test('')); // true
      console.log(/^千{0,2}$/.test('千'));  // true
      console.log(/^千{0,2}$/.test('千千')); // true
      console.log(/^千{0,2}$/.test('千千千'));  // false 

    </script>
3.字符类
(一)[ ] 匹配字符集合

1651059111046.png

[ ] 里面加上 - 连字符

  • 使用连字符 - 表示一个范围
  • 如:

[a-z] 表示 a 到 z 26个英文字母都可以 [a-zA-Z] 表示大小写都可以 [0-9] 表示 0~9 的数字都可以

1651059363450.png

[ ] 里面加上 ^ 取反符号

  • 比如: [ ^a-z ]匹配除了小写字母以外的字符 注意要写到中括号里面
<script>
      // [ab]  => 可以匹配 a  或者 b
      // console.log(/[ab]/.test('abc1A'));// true
      // console.log(/[ab]/.test('b'));// true
      // console.log(/[abc]/.test('c'));// true

      // 表示 a-z 任意的一个字母
      // console.log(/[a-z]/.test('c'));// true
      // console.log(/[a-z]/.test('d'));// true
      // console.log(/[a-z]/.test('123'));// false
      // console.log(/[a-d]/.test('a'));// true
      // console.log(/[a-d]/.test('g'));// false

      // 0-9 任意的一个数字
      // console.log( /[0-9]/.test("1") );// true
      // console.log( /[0-9]/.test("2") );// true
      // console.log( /[0-9]/.test("0") );// true

      // A-Z
      // console.log(/[A-Z]/.test("a"));// false
      // console.log(/[A-Z]/.test("B"));// true

      // 同时满足 0-9a-zA-Z
      /* console.log(/[0-9a-zA-Z]/.test('1'));// true
      console.log(/[0-9a-zA-Z]/.test('a'));// true
      console.log(/[0-9a-zA-Z]/.test('A'));// true
      console.log(/[0-9a-zA-Z]/.test(' '));// false */
    </script>
(二) . 匹配除换行符之外的任何单个字符
<script>
      //  . 表示除了(换行符tab之外)任意字符
      // console.log(/路/.test('飞')); // false
      // console.log(/./.test('飞')); // true
      // console.log(/路.飞/.test('路大飞')); // true
      // console.log(/路.飞/.test('路小飞')); // true
      // console.log(/路.飞/.test('路中飞')); // true
      // console.log(/路.飞/.test('路不飞')); // true
      // console.log(/路.飞/.test('路  飞')); // false
      // console.log(/路.飞/.test('路飞')); // false
      // console.log(/路.飞/.test('路 飞')); // true

      // \d 表示数字
      // console.log(/\d/.test("路飞"));// false

      // console.log(/\d/.test("1路飞"));// true
      // console.log(/\d/.test("路3飞"));// true

      // \D 不是数字之外的任意1个字符
      // console.log(/\D/.test("123"));// false
      // console.log(/\D/.test("12a3"));// true
      // console.log(/\D/.test("12a3"));// true

      // \w  字母、数字、下划线
      // console.log(/\w/.test("123"));//  true
      // console.log(/\w/.test("%%"));//  false
      // console.log(/\w/.test("%1%"));//  true
      // console.log(/\w/.test("%a%"));//  true
      // console.log(/\w/.test("%_%"));//  true

      // \W  除去了 字母 、数字、下划线 之外字符
      // console.log(/\W/.test("123"));// false
      // console.log(/\W/.test("1%23"));// true

      // \s  匹配空格
      // console.log(/\s/.test("123"));// false
      // console.log(/\s/.test("1 23"));// true

      // \S 除了空格之外的字符
    //   console.log(/\S/.test('1 23'));// true
    //   console.log(/\S/.test('1 2    '));// false
      // console.log(/\S/.test('   '));// false
    </script>
(三) 预定义:指的是某些常见模式的简写方式。

1651059771212.png

1651059811351.png

 <script>
     //日期格式
	 console.log(/^\d{4}-\d{1,2}-\d{1,2}/.test('2020-04-27'));
 </script>

测试正则案例

用户名/手机号/邮箱

    <script>
        //注册账号 用户名/手机号/邮箱

        //用户名规则--- 必须是字母,范围3-8
        const username = 'guliuyi'
        //设置用户名规则
        const nameRule = /^[a-zA-Z]{3,8}$/
        //要加上开始和结束边界符,如果不加 开头和结尾以其他符号开头也会返回true
        console.log(nameRule.test(username));

        //手机号规则  以数字1开头 第二个数字可以是35789 其他9位数字 (一共11个数字)
        const tel = '15625883210'
        //设置手机号规则
        const telRule = /^1[35789]\d{9}$/
        //同样要加上开始和结束边界符
        console.log(telRule.test(tel));

       //邮箱规则  
       // 邮箱名称  可以是字母或者数字  最少要有一个 {1,} 或者 +  //+表示至少出现一次
       // 固定的分隔符  @
       // 字母或者数字
       // 匹配一个.   => \. (要识别.本身 .前面务必加\ 否则.会被识别为除换行符外的任意一个符号)
       // 规定 com  cn
       const mail = 'gugu123@liuyi.com'
       const mailRule = /^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.c(om|n)$/
       console.log(mailRule.test(mail));
    </script>