web API day7

112 阅读3分钟

本地存储

本地存储特性:

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

localStorage

  1. 生命周期永久生效,除非手动删除 否则关闭页面也会存在。

  2. 可以多窗口(页面)共享(同一浏览器可以共享)。

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

本地存储

localStorage.setItem("要存储的元素",值)

获取数据

localStorage.getItem("存储的元素")

删除数据

localStorage.removeItem("要删除的元素")

清空所有数据

localStorage.clear();

注意:

  • 存储完的值,无论他原来是什么类型, 获取过来 返回都是字符串类型。

  • 本地存储 存复杂类型数据 如:对象数据和数组, 会导致数据丢失;他有固定规则,只能存简单类型的数据。

  • 想存储对象和数组的话 ,可以用JSON.stringify(要转换的元素),快速帮我们把对象和数组解析存储;再重新用JSON.parse(自定义名字),把他转换成数组,可以取出时使用。

    语法:

    localStorage.setItem("要存储的元素",值);
    let 自定义名字 = JSON.stringify(要转换的元素);
    //再转换成数组
    JSON.parse(自定义名字);
    

页面自动换肤-存储数据案例

<body>
   //input type="color" 有兼容性问题,比较少用,像ie都使用不了
    <input type="color">
    <script>
        let input = document.querySelector("input");

        //把刷新后的状态有背景颜色=上一次存储的背景颜色    放在触发事件外面
        document.body.style.backgroundColor = localStorage.getItem("input")

        //input 选择完毕时触发事件
        input.addEventListener("change", function () {
            //让背景颜色= input.value会显示#xxxxxx 你在input选择的颜色
            document.body.style.backgroundColor = input.value;

            //存储数据
            localStorage.setItem("input", this.value)
        })
    </script>
</body>

录入学生资料-数组本地存储案例

1649991326580

完成后示例:

<!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>
    <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 定义数组 负责存放表格要显示的数据
      // 获取本地存储中的数组(字符串格式)  转成 数组格式

      // 第一次打开页面的时候 ,本地存储里面会有数据吗
      //如果数据不存在 会显示null
       const strArr= localStorage.getItem("arr");
      let arr = [];

      if(strArr){
           // 有值 转成数组
        arr = JSON.parse(strArr);
      } else{
          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 会一直保存着,除非手动删除。
    <script>
        //sessionStorage 本地存储的用法和 localStorage 是一样的。
        //只是他存储的数据 在关闭页面后 ,数据就会丢失
        // localStorage 会一直保存,除非手动删除。

        //存储的内容 在 会话存储空间

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

补充知识点

dom元素属性

标签的属性有 两种:

  1. 固有属性 比如: id , href , src ,获取和设置比较方便,可以直接使用点语法。
<body>
    <a href="#" id="333"></a>
    <script>
        // 标签的属性有 两种:
        // 1.固有属性 比如: id , href , src  ,获取和设置比较方便,可以直接使用点语法。

        let a = document.querySelector("a");

        //  获取固有属性
        console.log(a.id) 
        console.log(a.href)

        //直接修改
        a.id="111"
        console.log(a.id)
    </script>
</body>

自定义属性

2.自定义属性

是自己给标签创建的属性名。

  • 自定义属性 不能直接通过点语法来获取和设置。
  • 获取 getAttribute ("自定义的属性名");
  • 设置修改 setAttribute ("自定义的属性名",“修改的内容”);
  • 删除掉属性 removeAttribute ("要删除的属性名")
<body>
    <a href="#" id="333" hello="你好"></a>
    <script>
        //自定义属性 不能直接通过点语法来获取和设置
        //获取 getAttribute("自定义的属性名")
        console.log(a.getAttribute("hello"))

        //设置修改 setAttribute("自定义的属性名",“修改的内容”)
        a.setAttribute("hello","再见")

        //删除掉属性 removeAttribute("要删除的属性名")
        a.removeAttribute("hello")
    </script>
</body>

h5 建议的自定义属性

h5建议的 自定义属性:

写法:

属性的时候 : 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>

小结:

标签的属性 有两种分为

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

2 自定义属性

​ 1 随机自己瞎命名

          <a  abc="123" >  

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

​ 2 h5建议 data- xxx

          <a  data-abc="123" >  

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

3 最强大是 (getAttribute) setAttribute removeAttribute

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

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

高阶函数

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

作用:后期 react阶段 会用到。

示例:

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

浏览器渲染页面的流程(了解)

1.重排:主要 修改了元素的大小,位置,定位+浮动

​ 会损耗浏览器的性能。

2.重绘: 主要修改; 像修改外观颜色字体颜色这些,性能损耗比较低。

3.最理想的情况: 不要出现重排重绘。

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

事件绑定-取消绑定

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

写法:

removeEventListener(“触发事件”,要取消的对应函数名)

注意:

  • 匿名函数无法取消绑定 ,因为对应的函数名不知道是什么,所有取消不了。

示例:

<body>
    <button>点击</button>
 

    <script>
        function func(){
            console.log('123456789')
        }

        function func2(){
            console.log("hhh")
        }

        let btn = document.querySelector("button");

        //给按钮绑定 点击执行func函数里的打印  
        //addEventListener 可以绑定多个同名事件
        btn.addEventListener("click",func);
        btn.addEventListener("click",func2);

        //加个延时器 5秒后执行
        //取消掉输出hhh的点击事件 removeEventListener(“触发事件”,要取消的对应函数名)
        setTimeout(function() {
            btn.removeEventListener("click",func2)
        }, 5000);

        // 注意: 匿名函数无法取消绑定 ,因为对应的函数名不知道是什么,所有取消不了
        
    </script>
</body>

事件流动

事件流动 实际上 有3个阶段:

1.最重要的 冒泡阶段

2.捕获阶段

3.目标阶段 (了解)

目标阶段

点击了最底层的标签 处在目标阶段。

字符串的方法

字符串转换的方法
toUpperCase()大写转小写
toLowerCase()小写转大写
str.split('')字符串转数组
    <script>
        //实际开发过程中 有很多需求要针对字符串做处理
        //js 帮我们封装了很多大量和实用的 字符串方法

        //先介绍一些

        let msg = "hello"
        let msg2 = "AABBCC"
         //大写转小写 toUpperCase()
         console.log(msg.toUpperCase()) ;
         //小写转大写 toLowerCase()
         console.log(msg2.toLowerCase()) ;


         //字符串转数组 str.split('')
         let str ="abcdefg" //想要变成数组["a","b","c","d","e","f","g"]
         console.log(str.split(''));

         let str2 ="a-b-c-d-e-f-g" //想要变成数组["a","b","c","d","e","f","g"]
         console.log(str2.split('-'));
    </script>

数组方法

数组转换的方法
join("")数组转字符串
要合并的数组1.concat(要合并的数组2)两个数组连接起来
    <script>
        //数组 补充常用方法
        //数组转字符串  join("")
        const arr = ["a","b","c","d",]
        const arr2 = ["a","b","c","d",]
        console.log(arr.join("")) //打印显示 abcd 字符串
        console.log(arr2.join("-")) //打印显示 a-b-c-d 字符串


        //数组和数组之间连接  要合并的数组1.concat(要合并的数组2)
        let arr3 =[1,2,3,4]
        const arr4 = ["a","b","c","d",]
        //将两个数组合并成一个数组
        console.log(arr3.concat(arr4));
        //打印显示[1,2,3,4,"a","b","c","d"]
    </script>

正则表达式

  1. 正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象
  2. 通常用来查找、替换那些符合正则表达式的文本,许多语言都支持正则表达式。

正则表达式在 JavaScript中的使用场景

  • 例如验证表单:用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配)。
  • 比如用户名: /^[a-z0-9_-]{3,16}$/
  • 过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等 。

语法

JavaScript 中定义正则表达式的语法有两种,先学习其中比较简单的方法:

1650011139231

1650011157481

示例:

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

        //判断这个字符串有没有 梦想 两个字
        const str = `斤斤计较经济界梦想哈哈哈哈`

        //定义规则 
        const reg = /梦想/;

        //规则和字符串 匹配  用 自己定义的规则名.test(要检测的字符串) 检测 
        console.log(reg.test(str));  //有的话 返回true 没有返回 false 

</script>

元字符

  • 普通字符: 大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。也就是说普通字符只能够匹配字符串中与它们相同的字符。

  • 元字符(特殊字符):

    • 是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。

    • 比如,规定用户只能输入英文26个英文字母,普通字符的话 abcdefghijklm….. 但是换成元字符写法: [a-z]

  • 参考文档:

边界符

边界符(表示位置,开头和结尾,必须用什么开头,用什么结尾)。

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

1650013026453

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

示例:

 <script>
        const str = `来得分哈`

//边界符 /^$/
     //边界^$,那里面的文字必须和边界符一模一样,否则返回false,多一个字都不行
     const reg = /^来得分哈$/; 
        
    //如果只加了^开头,那只要最前面和符号里一样就行,后面有多少字都会返回 true
    const reg = /^来/;    
        
   //如果只加了$结尾,那只要最后面的字和符号里一样就行,前面面有多少字都会返回true
    const reg = /分哈$/;     

     //规则和字符串 匹配  
     console.log(reg.test(str));  

</script>

量词

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

1650013295617

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

示例:

<body>
    <script>
        /* const str ="小文"
        const reg=/小文/;
        console.log(reg.test(str)); */
        //以上几行代码 可以简写:
        console.log(/小文/.test("小文"));

        //* 表示放在他前面的那一个字符 可以出现0次或者多次
        // console.log(/^文*$/.test(""));  //true
        // console.log(/^文*$/.test("文")); //true
        // console.log(/^文*$/.test("文文"));  //true
        // console.log(/^文*$/.test("文文文"));  //true



        //+ 表示放在他前面的那一个字符 可以出现1次或者多次
        // console.log(/^文+$/.test(""));  //false
        // console.log(/^文+$/.test("文")); //true
        // console.log(/^文+$/.test("文文"));  //true
        // console.log(/^文+$/.test("文文文"));  //true

        

        //? 表示放在他前面的那一个字符 可以出现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(""));  //false
        // console.log(/^文{2,}$/.test("文")); //false
        // console.log(/^文{2,}$/.test("文文"));  //true
        // console.log(/^文{2,}$/.test("文文文"));  //true



        // {n,m} 放在它前面的那一个字符  最少出现n次,最大是m次
        console.log(/^文{2,3}$/.test(""));  //false
        console.log(/^文{2,3}$/.test("文")); //false
        console.log(/^文{2,3}$/.test("文文"));  //true
        console.log(/^文{2,3}$/.test("文文文"));  //true

    </script>
</body>

字符类

预定义:指的是某些常见模式的简写方式。

1650016359484

  <body>
    <script>
      //  . 表示除了(换行符之外)任意字符
      // 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

      // \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('123'));// true
      // console.log(/\S/.test(' '));// false
      // console.log(/\S/.test('   '));// false
    </script>
  </body>

1650017422669

1650017455175

1650017469968

    <script>
        //[ab] =>可以匹配 a 或者 b
        // console.log(/[ab]/.test("a")); //true
        // console.log(/[ab]/.test("b")); //true
        // console.log(/[abc]/.test("c")); //true


        //[a-z] 表示a-z里的任意一个
        // console.log(/[a-z]/.test("a")); //true
        // console.log(/[a-z]/.test("b")); //true
        // console.log(/[a-d]/.test("f")); //false
        // console.log(/[a-d]/.test("123")); //false


        //[0-9] 0-9任意的一个数字
        // console.log(/[0-9]/.test("0")); //true
        // console.log(/[0-9]/.test("2")); //true
        // console.log(/[0-9]/.test("9")); //true
        // console.log(/[0-100]/.test("99")); //false 因为是字符串的原因这个只适用个位数的


      // A-Z   表示大写的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>
        //要求注册账户名 必须只能是字母,且长度大于3-8
        console.log(/[a-zA-Z]{3,8}/.test("111AaA2323594")) //这样还是显示true,所以是错的。因为这样的意思是只要字符串里有3个及以上的字母然后字母个数在3-8就会给true,所以要加上边界符。
       // 所以 需要把量词 边界符和字符结合使用 可以实现。
        console.log(/^[a-zA-Z]{3,8}$/.test("aasagdfi")) // true 这样就完成以上要求了


        //手机号码验证 
        //规则 以数字1开头 第二个数字可以是35789 其他9位数字 (一共11个数字)
        console.log(/^1[35789]\d{9}$/.test("15123456789")) //true
        //console.log(/^1[35789]\d{9}$/.test("135789123456789")) //false
        //console.log(/^1[35789]\d{9}$/.test("12123456789")) //false


        //邮箱名称
        //规则 
        // 1.前面可以是字母或者数字,最少要有一个{1,} 或者 +
        //2.固定的分隔符 @ 
        // 3.字母或者数字 也是最少要有1个 {1,} 或者 +
        //4. 一个固定的.  (注意直接写.的话是指除换行符外的任意一个符号) 要表示 . 本身 前面加个\就行  写法是 \.
        //5. 最后是com或者cn  写法是 c(om|n) 
        console.log(/^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.c(om|n)$/.test("6@2.cn")) //true
        console.log(/^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.c(om|n)$/.test("6@2.com")) //true
    </script>