API基础笔记

152 阅读19分钟

Web API基本认知

1 API

  1. Web APIs是W3c 组织的标准

  2. API (Application Programming Interface,应用程序编程接口) 是一些预选定义的函数,目的是提供应用与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节

  3. 简单理解: API是给程序员提供的一种工具,以便能更轻松想要完成的功能

    比如手机充电的接口:我们要实现充电这个功能:
    
    1.我们不关心手机内部变压器,内部怎么存储电等
    
    2.我们不关心这个充电线怎么制作的
    
    4.我们只知道,我们拿着充电线插进充电接口就可以充电
    
    5.这个充电接口就是一个 API 
    
  4. Web API 是浏览器提供的一套操作浏览器功能的页面元素的API(BOM和Dom)

  5. MDN 详细 API : developer.mozilla.org/zh-CN/docs/…

  6. 因为Web API很多.所以我们将这个阶段称为Web APIs

2 作用和分类

  1. 作用 : 就是使用JS去操作html 和浏览器
  2. 分类 : Dom(文档对象模型) BOm(浏览器对象模型)

3 什么是DOM

  1. DOM(Document Object Model——文档对象模型) 是用来呈现以及与任意HTML或XML文档交互的API
  2. 白话文: DOM是浏览器提供的一套专用用来操作页面内容的功能
  3. DOM作用:开发网页内容特效的实现用户交互

4 DOM树

DOM树是什么

  1. 将HTML 文档以竖装结构直观的表现出来,我们称之为文档树或DOM树
  2. 描述网页内容关系的名词
  3. 作用: 文档树直观的体现了标签与标签之间的关系

5DOM对象(重要)

1DOM对象:浏览器根据Html标签生成的JS对象

  1. 所以的标签属性都可以在这个对象上面找到
  2. 修改这个对象的属性会自动映射到标签身上

2 DOM的核心思想

  1. 把网页内容当做对象来处理

document对象

  1. 是DOM里提供的一个对象

  2. 所以它提供的属性和方法都是用来访问和操作网页内容的

  3. 网页所以的内容都在document里面

    // 列如
    document.write()
    

获取DOM对象

  1. 根据CSS选择器来获取DOM元素(重点)
  2. 其他获取DOM元素方法 了解

1 选择匹配的第一个元素

  1. 语法

    document.querySelector('css选择器')
    
  2. 参数: 包含一个或多个有效的CSS选择器 字符串

  3. 返回值:CSS选择器匹配的第一个元素,一个HTMLElement对象,如果没有匹配,则返回null

2 选择匹配的多个元素

  1. 语法

    document.querySelectorAll('css选择器')
    1.因为得到的是一个对象的集合,所以我们想要操作里面的元素就需要遍历
    2.得到元素对象是动态的
    3.如果获取不到元素,则返回为空的伪数组(因为获取不到对象)
    
    
  2. 参数: 包含一个或多个有效的CSS选择器 字符串

  3. 返回值:CSS选择器匹配的Nodelist 对象集合(返回值为一个伪数组有长度有索引号的数组但是没有pop() pish() 等数组方法想要得到里面的每一个对象,则需要遍历(for) 的方式获得)

  4. 哪怕只要一个元素,通过querySelectAll()获取过来的也是一个伪数组,里面只有一个元素而已(哪怕没有元素返回值也是一个空的伪数组)

3 其他获取DOM元素方法

  1. 根据ID获取一个元素

    document.getElementById('nav')
    
  2. 根据标签名称来获取dom元素 获得页面的全部div

    document.getElementsByName('div')
    
  3. 根据类名来获取元素 获得页面所有类名为container的

    document.getElementsByClassName('container')
    
  4. 获取body元素

     doucumnet.body  // 返回body元素对象
    
  5. 获取html元素

    document.documentElement  // 返回html元素对象
    

4总结案例

<!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>
    <script>
    //1.根据id来获取一个 dom
    // let nav =document.getElementById('nav')
    //2.根据标签名称来获取dom元素    一组dom元素
    //  let ps =document.getElementsByName('p')
    //3.根据类名来获取元素  一组元素
    //let divs =document.getElementsByClassName('container')

    //常用方法
    //获取一个
    document.querySelector('#nav')   //id
    document.querySelector('p')    //标签
    document.querySelector('.container')   //类
    //获取一组
    document.querySelectorAll

    </script>
</body>
</html>

4 设置/修改DOM元素内容

DOM对象都是根据标签生成的,所以操作标签,本质上就是操作DOM对象

就是操作对象使用的点语法

如果想要修改标签元素的里面内容, 则可以使用如下几种方法

1 document.write()方法

  1. 只能将文本内容追加到前面的位置

  2. 文本中包含的标签会被解析

    //永远都只是追加操作,且只能位置</body>前
    document.write( ' Hello world! ' );
    document.write( ' <h3>你好,世界!</h3>')
    
    

2 对象.innerText属性

  1. 将文本内容添加/更新到任意标签位置

  2. 文本包含的标签不会被解析

    // innerText将文本内容添加/更新到任意标签位置
    let info = document.getElementById( 'info ')
    //intro.innerText =‘嗨、我叫叼毛!'
    info.innerText = '<h4>嗨~我叫叼毛!</h4>'
    

3 对象.innerHTML属性

  1. 将文本内容添加/更新到任意标签位置

  2. 文本中包含的标签会被解析

    // 2. innerHTML属性
    box.innerHTML = '<h3>前端程序员<br>的头发都很多</h3>'
    

4 案例总结

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>3种设置文本内容的方式</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
    </ul>
    <script>
      //  以后就很少用了 document.write 功能弱 只能把标签写在  /body  标签上面
      // document.write
      document.querySelector('li:nth-child(2)').innerText = '<button>随便修改</button> ';
      document.querySelector('li:nth-child(3)').innerHTML ='<button>随便修改</button> ';

      /* 
         3种实现在标签中写 动态设置文本
      1  document.write 只能在body标签的中写 以后 很使用它
      2  innerText 只能设置文本,不能解析 html字符串
      3  innerHTML 可以设置文本 也可以解析html字符串 
     
       */
    </script>
  </body>
</html>

5设置/修改DOM元素属性

设置/修改元素常用属性

  1. 通过JS设置/修改标签元素属性, 比如通过src更换图片

  2. 最常见的属性比如: href , title , src

  3. 语法

    对象.属性 =值得
    
  4. 代码写法

    //1.获取元素
    let pic=document.querySelector("img");
    //2. 操作元素
    pic.src ='./images/01.jig'//(图片路径)
    pic.title = '这是一个图片'
    
    
  5. 综合案例

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
        />
        <title>12-dom元素-属性.html</title>
        <style>
          * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
          }
        </style>
      </head>
      <body>
        <a href="http://www.baidu.com">跳转到</a>
        <img src="./images/1.jpg" title="有惊喜" alt="" />
        <p id="nav"></p>
        <input type="text" />
        <button type="button"></button>
        <h1 class="dfdf"></h1>
        <script>
          /* 
           a 标签身上的  href 图片 src alt  id type class 属性 
            1 获取标签对应的dom元素
            2 dom.属性名=属性值 
           */
    		//获取a标签
           let aDom = document.querySelector('a');
          // 修改a标签的属性
           aDom.href = 'https://www.jd.com/?cu=true&utm_source=baidu-pinzhuan&utm_medium=cpc&utm_campaign=t_288551095_baidupinzhuan&utm_term=0f3d30c8dba7459bb52f2eb5eba8ac7d_0_d0a1ddf590ad4526b437d384a79421aa';
    	
            //获取img标签
          let imgDom=document.querySelector("img");
          // 修改图片的src
          imgDom.src="./images/2.jpg";
    
          // 动态修改 title属性
          imgDom.title="你妈妈叫你回去吃饭";
        </script>
      </body>
    </html>
    
    

1 设置/修改元素样式属性

  1. 通过JS设置/修改标签 元素的样式属性
  2. 比如通过 轮播图小圆点自动更换颜色样式
  3. 点击按钮可以滚动图片,这是移动的图片的位置left等等
通过style属性操作css
  1. 语法

    对象.style.样式属性 = 值
    
  2. 写法

    <body>
        <div>我的室友潮吧彭炎</div>
        <script>
            // 1 获取dom元素
          let div = document.querySelector('div')
          //console.log(div);
        // 2 开始修改   
          // 会出现 单词写错或者 值写错 写漏
          // 那段代码没有效果 就去看那段代码 
          div.style.fontSize='100px'  //文字大小
          div.style.color='red'		//文字颜色
          div.style.backgroundColor ='pink'	//背景颜色	
          div.style.width='1200px'	//宽度	
          div.style.height='1000px'	//高度
          div.style.textAlign='center'	//文字居中
          div.style.lineHeight= '1000px'	//行高
          div.style.margin=`100px auto`	//绝对水平居中
        </script>
    </body>
    
2 操作类名(className)操作CSS
  1. 语法

    //active  是一个css类名
    元素.className = 'active'
    //1. 由于class是关键字, 所以使用className去代替
    //2. className是使用新值换旧值, 如果需要添加一个类,需要保留之前的类名
    
3通过calssList操作类控制CSS

为了解决className容易覆盖以前的类名, 我们可以通过classlist方式追加和删除类名

  1. 语法

    //追加一个类 添加一个class
    元素.classList.add('类名')
    //删除一个类  单独来指定移除一个class
    元素.classList.remove('类名')
    //切换一个类
    元素.classList.toggle('类名')
    //切换 (如果本来有,那我就移除  , 如果本来没有,那我就添加)
    

6.设置/修改 表单元素 属性

表单很多情况,也需要修改属性,比如点击眼睛,可以看到密码,本质是把表单类型转换为文本框 正常的有属性有取值的 跟其他的标签属性没有任何区别

  1. 获取: DOM对象.属性名

  2. 设置:DOM对象.属性名 = 新值

        //按钮
    	<button class="code" disabled>发送验证码</button>
    	button.disabled=true   禁用
        button.disabled=false  启用
        
        //单选框 多选框
        <input type="checkbox" class="isarg" checked />
        // 设置勾选上
        isarg.checked = true;
        // 不勾选
        isarg.checked = false;
    
    	//下拉列表
    	option.selected=true  选中 
        
        //文本域
         // 通过js的方式来设置内容  三种方式都一样
          textarea.value=`<h1>标题</h1>`;  //  ok
          textarea.innerText=`<h1>标题</h1>`; //  ok
          textarea.innerHTML=`<h1>标题</h1>`;  //  ok
    
    
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
        />
        <title>表单属性设置.html</title>
        <style>
          * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
          }
        </style>
      </head>
      <body>
        <input type="text" class="username" />
        是否同意协定
        <input type="checkbox" class="isarg" checked />
    
        <button class="code" disabled>发送验证码</button>
    
        <select class="sel">
          <option>去泰国</option>
          <option>去非洲</option>
          <option>去印度</option>
          <option>去啊富汗</option>
        </select>
    
    
    
        <textarea name="" id="" cols="30" rows="10"></textarea>
        <script>
          /* 
          innerText innerHTML 主要是用来设置 双标签的文本内容的
          
           */
          // 获取一下表单 dom元素
          let username = document.querySelector('.username');
          // 复选框
          let isarg = document.querySelector('.isarg');
          // 按钮
          let code = document.querySelector('.code');
    
          // 设置文本内容
          // username.innerText = '我的用户名';
    
          // 设置输入框的文本内容
          username.value = '我的用户名';
    
          // 设置勾选上
          // isarg.checked = true;
          // 不勾选
          // isarg.checked = false;
    
          // 设置按钮 可以启用 可以点击
          // disabled 禁用
          // code.disabled = true;// 禁用
          code.disabled = false; // 启用
    
          // select 选中
          let option = document.querySelector('option:nth-child(4)');
          // option.select = true; // 错误的单词
          option.selected = true; // 正确的单词
    
    
          // checked  disabled  selected
    
    
          /* 
          表单属性的总结
    
          1 设置普通的输入框  input.value ="表单的值"
          2 设置 按钮的禁用 
            button.disabled=true   禁用
            button.disabled=false  启用
          3 设置单选框或者复选框
            radio.checked=true   选中
            checkbox.checked=false  取消选中
    
          4 设置下拉列表 select
            option.selected=true  选中 
    
          5 文本域标签 有点点特殊 !
          
           */
    
    
        //文本域标签
         // 获取文本域中的值
    
    
          // console.log(textarea.value); // 获取 OK <h1>你好</h1>
          // console.log(textarea.innerText); // 获取  不OK
          // console.log(textarea.innerHTML); // 获取   OK  &lt;h1&gt;你好&lt;/h1&gt;
    
    
        // value和innerHTML的区别
        // 设置 textarea 里面文本的内容的时候
        // 可以选择 在标签内写文本即可
        // 想要获取 内容
        // .value  原样获取内容
        // .innerHTML 获取的内容如果包含html 会转译
    
    
        // 通过js的方式来设置内容  三种方式都一样
          // textarea.value=`<h1>标题</h1>`;  //  ok
          // textarea.innerText=`<h1>标题</h1>`; //  ok
          // textarea.innerHTML=`<h1>标题</h1>`;  //  ok
        </script>
      </body>
    </html>
    
    

7定时器-间歇函数

1定时器函数介绍
  1. 网页中经常会需要一种功能: 每隔一段时间需要自动执行一段代码,不需要我们手动去催发
  2. 例如: 网页中的倒计时
2 定时器函数基本使用
  1. 开启定时器

  2. 语法

    setInterval(函数,间隔时间)
    
  3. 写法

    //写法一
    function repeat() {
            console.log('前端程序员,头发多');
          }
    setInterval(repeat, 1000);
    
    
    //写法二  setInterval(repeat, 1000);匿名函数写法
    setInterval(function(){
            console.log("头发没有啦");
          },1000);
     // 函数 负责 定时执行的业务
     // 单位毫秒   1000毫秒=1秒    每隔一秒执行一次函数
    
3关闭定时器
  1. 语法

    let变量名= setInterval(函数,间隔时间)
    clearInterval(变量名)
    //一般不会刚创建就停止,而是满足一定条件再停止
    
  2. 写法

     //方法一
    
    let timeId = setInterval(function () {
             console.log('准备吃晚饭');
           }, 1000);
    console.log(timeId);   //打印
    clearInterval(timeId); //清除定时
    
    
    //方法二
    let index = 0
    let timeId = setInterval(function () {
            index++;
            console.log('开始追了', index);
            // 判断是否满足条件了
            if (index === 30) {
              // 放弃 没有缘分
              clearInterval(timeId); //清除定时
            }
          }, 100);
    

8 事件概述

1什么是事件

事件是在编程是系统内发生的动作或者发生的事情,比如用户在网页上单击一个按钮

2 什么是事件监听

就是让程序检测是否有事件产生,一旦有事件催发,就立即调用一个函数做出响应,也称为注册事件

3 语法
元素.addEventListener('事件',要执行的函数)
btn1.addEventListener('click', function () {
       console.log('开始抽奖啦');
  });
4 事件监听三要素

1 事件源: 那个dom元素被事件催发了,要获取dom元素

2 事件: 用什么方式催发, 比如鼠标单击click, 鼠标经过 mouseover等

3 事件调用的函数: 要做什么事

5 案例
//1.获取元素
let html= document.querySelector('html')
//2.事件监听 (注册事件)
      html.addEventListener('mousemove',function () {
          console.log('潮吧肖耀');
      })
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>05-事件初体验.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      div {
        height: 300px;
        background-color: aqua;
      }
    </style>
  </head>
  <body>
    <button class="btn1">抽奖</button>
    <button class="btn2">退出抽奖</button>
    <div></div>
    <script>
      /* 
      触发事件dom元素
      事件类型
      事件触发了 做业务 函数
       */

      let btn1 = document.querySelector('.btn1');

      // 注册事件
      // btn1.addEventListener("事件类型","处理函数")

      // click 鼠标单击
      btn1.addEventListener('click', function () {
        console.log('开始抽奖啦');
      });

      let btn2 = document.querySelector('.btn2');
      btn2.addEventListener('click', function () {
        console.log('退出抽奖啦');
      });
      let div = document.querySelector('div');
      // mouseover  鼠标移入到 div 的区域内
      div.addEventListener('mouseover', function () {
        console.log('小哥快点进来');
      });
      let html= document.querySelector('html')
      html.addEventListener('mousemove',function () {
          console.log('潮吧肖耀');
      })
    </script>
  </body>
</html>

9 事件基础

1 JavaScript 使我们有能力创建动态页面,而事件是可以被JavaScript 侦测到的行为

2 简单理解: 催发----响应机制

3 网页中的每一个元素都可以产生某些可以催发JavaScript的事件,例如,我们可以在用户点击某些按钮时产生一个事件,然后去执行某些操作

4 案例

//页面中有一个按钮,当鼠标点击按钮的时候,弹出“你好”警示框。
/*
1.获取事件源(按钮)
2.注册事件(绑定事件),使用 onclick
3.添加事件处理程序(采取函数赋值形式)
(编写事件处理程序,写一个函数弹出 alert 警示框)
*/
<buttton class="btn">点我</button>
var btn = document.getElementById('.btn');
btn.onclick = function() {
  alert('你好吗');  
};

1常见的鼠标事件
鼠标事件触发条件
click鼠标点击左键触发
mouseover ,mouseenter鼠标经过触发
mouseout ,mouseleave鼠标离开触发
focusr获得鼠标焦点触发
blu失去鼠标焦点触发
mousemove鼠标移动触发
mouseup鼠标弹起触发
mousedown鼠标按下触发
contextmenu用户点击鼠标右键打开上下文菜单时触发
dblclick鼠标双击左键
2 焦点事件
焦点事件表单获得光标
focus获得焦点
blur失去焦点
3 键盘事件
键盘事件键盘触发
Keydown键盘按下触发
Keyup键盘抬起触发
keypress键盘按键被按下并松开
4 文本事件
文本事件表单输入触发
input用户输入事件
5 字符串(补充)也能和数组一样
  1. 类似数组的特性

  2. 属性length 当前字符串的长度

  3. 字符串也可以通过下标来访问

  4. 字符串

          // 字符串有 数组的长度length
           let str="你们好呀"; 
            str[0]=你 
            str[1]=们
          // 字符串也可以循环
    	      for (let index = 0; index < str.length; index++) {
              console.log(str[index]);
         	 }
    
6 环境对象(this)

this =表示 我自己 this整体的知识

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

作用: 弄清楚this的指向, 可以让我们代码更简洁

  1. 函数的调用方式不同,this指代的对象也不用

  2. 谁调用, this 就是谁 是判断this 指向的粗略规则

  3. 那个元素绑定点击事件,那个元素就是this

  4. 直接调用函数,其实相当于Window.函数,所以this指代window

          // 需求: 点击每一个 li标签 都可能 打印出 被点击的li标签的文本内容即可
          let liList=document.querySelectorAll("li");
    
          for (let index = 0; index < liList.length; index++) {
            liList[index].addEventListener("click",function () {
              // console.log(liList[index].innerText);
              console.log(this.innerText); // this = 表示 我自己   this整体的知识
            })
          }
    
7 排他思想

先用循环把所以标签都格式化(大家都一样)

然后再通过this或下标 找到自己或者对应的元素(再添加样式或类)

      // 先获取到每一个li标签
      // 再li标签绑定点击事件

      // 写处理其他所有的元素 让让他们的背景颜色都变成白色
      // 事件触发 设置 被点击的li标签 选中的样式

      let liList = document.querySelectorAll('li');
      for (let index = 0; index < liList.length; index++) {
        liList[index].addEventListener('click', function () {
          // 给被点击的li标签加上选中样式
          // liList[index].style.backgroundColor = 'red';
          // 先设置每一个li标签的背景颜色 成 白色
          for (let j = 0; j < liList.length; j++) {
            liList[j].style.backgroundColor = '#fff';
          }
          // 再单独设置 被点击的li标签  变成红色
          this.style.backgroundColor = 'red';
        });
      }

8 高阶函数

案例示范

节点操作

节点操作
  1. dom节点
  2. dom树里每一个内容都称之为节点
查找节点
  1. 能够具备根据节点关系查找目标节点能力
1 父节点

parentNode 属性

返回最近一级的父节点 找不到返回为null

	<div>
      <button>目标元素</button>
    </div>
        // 先获取button 目标元素
      let button = document.querySelector('button');
      // 修改一下父元素的背景颜色
	//子元素 . 父元素    修改样式
      button.parentNode.style.backgroundColor = 'red';
2子节点 -----children(重点) ---常用
  1. 仅获得所以元素节点

  2. 返回的还是一个伪数组

            1 this = 当前被点击的ul标签 
            2 this.children 获取到 所有的ul的子元素 数组
            3 遍历 children 获取到中的每一个li标签
            4 li.style.display="none"
    
3 兄弟节点
  1. 上个兄弟- previousElementSIbling

  2. 下个兄弟 - nextElementSibling

  3. 给那个标签设置了对应的兄弟节点, 那么就能修改它对应的样式

          //  1 获取所有的li标签 数组
          let lis = document.querySelectorAll('li');
    
          // 2 遍历 绑定点击事件
          for (let index = 0; index < lis.length; index++) {
            // 3 事件触发了
            lis[index].addEventListener('click', function () {
              // 上一个兄弟 设置 蓝色
              this.previousElementSibling.style.backgroundColor = 'blue';
              // 下一个兄弟 设置 绿色
              this.nextElementSibling.style.backgroundColor = 'green';
            });
          }
    
4 增加节点-createElement(创建)-appendChild(插入)- insertBefore-(指定插入)

一般情况下,我们新增节点,按照如下操作:

创建一个新的节点

1 创建节点

即创造出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点

只创建节点,在网页中是看不见的,还要插入

创建元素节点方法:

        // 1 创建一个 li 标签 节点
        let li=document.createElement('li')
        console.log(li);
2 插入节点

2-1 appendChild- 插入到父元素的最后一个子元素

要想在界面看到,还得插入到某个父元素中

        // 要给插入li加样式
        li.innerHTML='这是JS创建的li'
        li.style.backgroundColor='red'

        // 2 吧 li 标签插入到  ul 标签中
        let ul=document.querySelector('ul')
        ul.appendChild(li)//把li标签插入到ul 中 父元素的底部 插入子元素

2-2 移动-剪切

appendChild 插入元素的功能 | 剪切

1 appendChild(元素) 如果该元素是已经存在网页中, appendChild作用类似 移动

2 appendChild(元素) 如果该元素新创建的, appendChild作用类似 简单的插入

      // 先获取左边的第一个li标签
      let li = document.querySelector('.left li:nth-child(1)');
	// 获取右边的 Ul 标签
      let rightUl = document.querySelector('.right');
      // 把li标签插入到右边的ul中
      rightUl.appendChild(li);
3 insertBefore-可以插入到指点元素位置

父元素.insertBefore(要插入的元素,哪个元素的上面)

insertBefore 也能插入元素 功能也类似 appendChild

1 如果要插入的元素 是已经存在的 那么insertBefore作用 移动

2 如果要插入的元素 是新创建的 insertBefore作用 仅仅 插入

时间对象

1 时间对象: 用来表示时间的对象

2 作用: 可以得到当前系统时间

1 实际化

  1. 在代码中发现了new关键字时, 一把将这个操作称为实际化

  2. 创建一个事件对象并获取时间

  3. 获得当前时间

    let data = new Date()
    
  4. 获得指定时间

    let date = new Date ('1999-11-11')
    

2 时间对象方法

因为时间对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用得格式

方法作用说明
getFulllYear()获得年份获取四位年份
getMonth()获得月份取值为0~11
getDate()获得月份中的每一天不同的月份取值也不相同
getDay()获得星期取值为0~6
getHours()获得小时取值为0~23
getMinutes()获得分钟取值为0~59
getSeconds()获得秒取值为0~59

3 获取当前时间案例

  <script>
        let div =document.querySelector('div')
        setInterval (function () {
            let date =new Date()

            let year = date.getFullYear() //年
            let month = date.getMonth() + 1   //月
            let date1 = date.getDate() //号
            let day = date.getDay()   //星期几
            let hours = date.getHours()   //时
            let minutes = date.getMinutes()   //分
            let seconds = date.getSeconds()   //秒
            div.style.fontSize='30px'
            div.innerHTML=`${year}${month}${date1}号<br>星期${day}<br>${hours}${minutes}${seconds}秒`
            
        },1000)
      
    </script>

4 时间戳

1 什么是时间戳

是指1970年01月01日00时00分00秒起至现在的毫秒,他是一种特殊的计量时间的方式

2 三种方式获取时间戳

  1. 使用getTime()方法

    //1.  实例化
    let date = new Date()
    // 2.  获取时间戳
    console.log(dat.getTinme())
    
  2. 简写+new Date()

     console.log(+(new Date()) );
    //只要日期对象   可以使用 +将整个对象 转成 时间戳
    
  3. 使用Date.now()

     console.log(Date.now() );
    

事件对象

1 事件对象是什么

  1. 也是个对象,这个对象里有事件触发时相关信息
  2. 例如: 鼠标点击事件,事件对象就存了鼠标点在那个位置等信息

如何获取

  1. 在事件绑定的回调函数的第一个参数就是事件对象

  2. 一般命名为event , ev, e

     const btn = document.querySelector('button')
            //元素.                                 事件对象           
             btn.addEventListener('click',function (event) {
                console.log(event);
            })
    

1 . 1 获取时间对象

部分常用属性

  1. type 获取当前的事件类型

  2. clienX/ clienY 获取逛遍相对于浏览器可见窗口左上角的位置

  3. offsetX/offsetY 获取光标相对于当前DOM元素左上角的位置

  4. key 用户按下的键盘键的值 现在不提倡使用keyCode

       <div>点击点击</div>
        <script>
          // 获取按钮
          const btn = document.querySelector('div');
    
          btn.addEventListener('mousemove', function (event) {
            // console.log(event.type); // 输出当前的事件类型  少用
            // console.log(event.clientX,event.clientY ); // 返回 鼠标的位置-参照物 页面的左上角即可
            console.log(event.offsetX,event.offsetY);// 返回鼠标的坐标,参照物 是被点击的元素的左上角
          });
        </script>
    
  5. 小鸟跟随鼠标案例

       <h1>用户鼠标不要移动那么快</h1>
        <!-- <div></div> -->
        <img src="./images/xn.png" alt="" />
        <script>
          /* 
          1 给body标签 绑定 鼠标移动事件  
            body也是一个普通的块级元素 高度由内容撑开 同时 div使用了定位-脱标 body标签没有高度 
          2 事件触发了 获取 事件对象的坐标 clientX 
          3 把坐标设置给div的left top
           */
    
          // const div = document.querySelector('div');
          const img = document.querySelector('img');
          document.body.addEventListener('mousemove', function (event) {
            const left = event.clientX;
            const top = event.clientY;
    
            img.style.left = left + 'px';
            img.style.top = top + 'px';
          });
        </script>
    

2 事件流

2.1 事件流与两个阶段说明

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

    image-20220413115608667

  2. 说明:假设页面里有个Div,当触发事件时,会经历两个阶段,分别是捕获阶段,冒泡阶段

  3. 简单来说:捕获阶段是 从父到子 冒泡阶段是从子到父

2.2 事件捕获和事件冒泡

  1. 事件冒泡概念:

  2. 当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发, 这一过程被称为冒泡

  3. 简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件

  4. 事件冒泡是默认存在的

      /* 
          事件流动 
          1 给多个父子结构的标签绑定事件, 先点击了子元素, 产生事件流动
          2 事件流动 分成了两个阶段
            1 捕获阶段   父节点 流动到 子节点
            2 冒泡节点   子节点 流动到 父节点   默认
            3 例子:
              人 跳水 
              1 水上 水里面 不断下沉 
            4 事件流动方向 默认是 使用了冒泡 - 点击儿子标签 触发 儿子->父亲->爷爷
    
          3 我们可以修改触发事件 让它选择使用 捕获阶段还是冒泡阶段(默认)
            addEventListener 可以选择使用冒泡还是捕获
            addEventListener(事件类型,事件处理函数,捕获还是冒泡(默认值 false,可以省略))
            addEventListener("click",function(){}, true )
    
          4 总结
            1 捕获和 冒泡 特点 了解 
            2 默认情况  冒泡 如果想要修改 可以 addEventListener 第三个参数 传入 true即可
            3 以后的代码开发过程中,还是继续使用默认的 冒泡阶段 
    
    
          
           */
    

阻止事件流动

  1. 因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素

  2. 若想把事件就限制在当前元素内,就需要阻止事件流动

  3. 阻止事件流动需要拿到事件对象

  4. 此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效

         // 阻止事件冒泡
              event.stopPropagation();
            }
          );
    
    
          /* 
          引出新的知识 阻止冒泡! 下一节课 优雅的方式来解决刚才的问题! 
          在事件对象中 event 找到一个方法 停止冒泡  event.stopPropagation();
          
           */
    
  5. 阻止默认行为,比如链接点击不跳转,表单域的不提交

       /* 
          1 a标签的点击跳转
          2 form表单中button点击刷新行为
            1 阻止默认行为 - form表单 有一个 submit 事件 理解提交表单的触发-点击按钮的时候触发
            2 给button按钮绑定点击事件 也去阻止试试
            3 给button按钮 添加一个 type="button" 属性 
            4 换成 input标签 type="button"
            5 把button 移出form表单的区域 
    
          使用新技术 阻止标签默认行为 
           */
          const a=document.querySelector("a");
          const form=document.querySelector("form");
          const button=document.querySelector("button");
          a.addEventListener("click",function (event) {
            console.log("a标签的点击触发啦");
            // 阻止a标签的默认行为,让他不要跳转
            event.preventDefault();
          })
    

3 事件委托

事件委托是利用事件流的特征解决一些开发需求的知识技巧

  1. 优点: 给父级元素加事件(可以提高性能)

  2. 原理: 事件委托其实是利用事件冒泡的特点,给父元素添加事件,子元素可以触发

  3. 实现: 事件对象 .target 可以获得真正触发事件的元素

      <script>
          // 点击那个一li标签 颜色设置为红色
          // 以前获取到每一个li标签 数组  遍历他们 按个绑定点击事件
          // const liList=document.querySelectorAll("li");
          // for (let index = 0; index < liList.length; index++) {
          //    liList[index].addEventListener("click",function () {
          //      this.style.backgroundColor="red"
          //    })
          // }
    
    
          // 事件委托
          const ul=document.querySelector("ul");
          ul.addEventListener("click",function (event) {
            //  event.target 有可能是ul标签,有可能是li标签,还有可能是 a标签 
            // 一会再来解决这个问题。
            event.target.style.backgroundColor="red";// 不够完美的
            // event.target 你当前点击的是哪个标签(点击最深最底层的那个标签即可)
            // console.log(event.target);// 获取到被点击的li标签 
          })
    
  4. 就业榜案例

    <!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 定义数组 负责存放表格要显示的数据
          let 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);
    
            // 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);
    
              // 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>
    
    
  5. 总结

  6. 事件委托给了谁? 父元素

  7. 如何找到真正触发的元素? event.target 事件对象.target

滚动事件和加载事件

1 .1 滚动事件

  1. 当页面进行滚动时触发的事件

  2. 为什么要学? 很多网页需要检测用户滚动到某一个区域后做一些处理,比如固定导航栏,比如返回顶部

  3. 事件名: scroll

  4. 监听整个页面滚动

     //谁要滚动  就给父元素 添加滚动事件
            /* window.addEventListener('scroll',function(){
                console.log('我开始滚动了');
            }) */
            const div = document.querySelector('div')
            div.addEventListener('scroll',function () {
                console.log('div 开始滚动');
            })
    
  5. 固定导航栏

       const header = document.querySelector('header')
            const nav = document.querySelector('nav')
            window.addEventListener('scroll',function(){
                const scrollTop = document.documentElement.scrollTop
                if(scrollTop>=300){
                    nav.classList.add('fixed')
                    header.style.marginBottom= 200+'px'
                }else{
                    nav.classList.remove('fixed')
                    header.style.marginBottom=0
                }
            })
    
  6. 小火箭案例

      /* 
          步骤:
          1 设置页面的高度 200vh  设置渐变色
          2 先完成静态结构
            1 定位 右下角 火箭图片
            2 鼠标移上去 火箭图片切换- 会动的火箭图片
          3 页面滚动到一定的距离  1500
            让小火箭显示出来
            否则 小火箭就隐藏
           */
    
          const a = document.querySelector('a');
    
          window.addEventListener('scroll', function () {
            //  获取页面滚动的距离
            const scrollTop = document.documentElement.scrollTop;
            if (scrollTop > 700) {
              // 显示火箭
              a.style.display = 'block';
            } else {
              // 隐藏
              a.style.display = 'none';
            }
          });
    
          a.addEventListener("click",function () {
            document.documentElement.scrollTop=0;
          })
    加动画返回顶部效果
     a.addEventListener('click', function () {
            // document.documentElement.scrollTop = 0;
            // console.log(document.documentElement); // 就是根标签 html
    
            // 慢慢的来设置 scrollTop 减少为0 即可
            let timeId = setInterval(function () {
              document.documentElement.scrollTop -= 20;
              console.log('定时器执行', document.documentElement.scrollTop);
    
              if (document.documentElement.scrollTop === 0) {
                // 清除定时器
                clearInterval(timeId);
              }
            }, 10);
          });
    

1 .2 加载事件

  1. 加载外部资源(如图片,外联CSS和JavaScript等)加载完毕时触发的事件

  2. 为什么要学? 有时候需要等页面资源全部处理完了做一些事情

  3. 事件名: load

  4. 监听页面所有资源加载完毕

    //页面加载事件
          window.addEventListener('load',function(){
            //执行代码console.log('load 标签加载完毕-标签对应外部资源加载完毕');
          })
    
  5. 注意: 不光可以监听整个页面资源加载完毕,也可以针对某个资源绑定load事件

  6. 只是加载标签而已 很快 DOMContentLoaded 快

元素大小和位置

image-20220414222749447

1 scroll家族

  1. scrollWidth 获取元素实际宽度,也就是可滚动的距离大小,不包括滚动条
  2. scrollHeight 获取元素实际高度,也就是可滚动的距离大小,不包括滚动条
  3. scrollTop 获取元素被卷去的头部距离
  4. scrollLeft 获取元素被卷去的左边距离

2 offset家族

  1. offsetWidth 获取元素自身的宽度包括边框,padding
  2. offsetHeight 获取元素自身的高度包括边框,padding
  3. offsetTop 获取元素自身带有定位的父元素的上偏移
  4. offsetLeft 获取元素自身带有定位的父元素的左偏移

3 client家族

  1. clientWidth 获取元素可视区的宽度包括padding,不含边框
  2. clientHeight 获取元素可视区的高度包括padding,不含边框
  3. clientTop 获取元素上边框的大小
  4. clientLeft 获取元素上边框的大小

window对象

1 BOM(浏览器对象模型)

  1. BOM(Browser Object Model )是浏览器对象模型
  2. window 是浏览器内置中的全局对象, 我们所学习的所有Web APIs 的知识内容都是基于window对象实现的
  3. window 对象下包含了 navigation , location , doncument , history , scree 五个属性,即所谓的BOM(浏览器对象模型)
  4. document 是实现DOM的基础, 他其实是依附于window的属性
  5. 注: 依附于window 对象的所有属性和方法 , 使用时可以省略window

2 定时器 -延时函数

  1. JavaScript内置的一个用来让代码延迟执行的函数,叫setTimeout

    setTimeout(回调函数,等待的毫秒数)
    
    
  2. setTimeout仅仅执行一次,所有可以理解为就是把一段代码延迟执行,平时省略window

  3. 清除延时函数

     let timeid = setTimeout(function () {
            console.log('猜猜我是谁');
          }, 5000);
          // 取消延时器
          clearTimeout(timeid);
    
  4. 延迟关闭广告-案例

    <script>
          /*   // 延时器 - 只会执行一次而已
          let timeid = setTimeout(function () {
            console.log('猜猜我是谁');
          }, 5000);
          // 取消延时器
          clearTimeout(timeid); */
            setTimeout(function(){
                document.querySelector('.box').style.display='none'
            },5000)
        </script>
    

递归

<script>
      /* 
      递归
      1 一个函数调用自己  

      2 使用场景
        有一个函数,可以打印出 一个dom元素的所有祖先元素 
        不可能提前知道 这个a标签有多少个父元素 

        这个函数接收一个参数,= dom 
        如果这个dom元素有父元素,就继续调用自己函数


      3 使用场景
        1 假设你现在得了肺炎 警察叔叔 
          先找你 ->  找你的邻居(得了肺炎) -> 找你的邻居的邻居(得了肺炎)->找你的邻居的邻居(得了肺炎)...
          直到找到一个邻居 没事  警察叔叔 不找结束了 
       */
      // let index = 0;

      // function func() {
      //   index++;
      //   console.log(index);
      //   func();
      // }

      // func();

      const button = document.querySelector('button');

      getParent(button);
      function getParent(dom) {
        console.log(dom);
        if (dom.parentNode) {
          // 如果有父元素
          getParent(dom.parentNode);
        } else {
          console.log('结束啦');
        }
      }
    </script>

3 JS执行机制

4 location对象

  1. 使用a标签href 属性 可以实现页面跳转

  2. 在js中,也可以直接跳转 location.href 来跳转

  3. location.href也可以实现刷新 location.href = location.href

  4. location.reload()刷新 (true) 强制刷新

  5. search 获取url 上? 问号 后面一串字符

  6. hash 学习到了vue阶段 就会用到获取# 后面一串字符

     const button = document.querySelector('button')
            button.addEventListener('click',function () {
                //location.href = 'http://www.baidu.com'//不是链接标签也可以设置跳转
                //console.log(location.href); ====http://127.0.0.1:5500/6-day/13-location.html
    
                //刷新功能
                //location.href = location.href //刷新功能
    
               //console.log( location.search);
                //console.log(location.reload(true));  是个方法  需要加括号()
                //console.log(location.hash);
            })
    

5 navigation对象

navigation 的数据类型是对象,该对象下记录了浏览器自身的相关信息

6 history对象

history的数据类型是对象,该对象与浏览器地址栏的操作相对应,如前进,后退,历史记录等

  1. back() 可以后退功能
  2. forward() 前进功能
  3. go(参数) 前进后退功能 参数如果是1 前进一个页面 如果 -1 后退一个页面

7 swiper 插件 --轮播图

本地存储

1 本地存储特性

随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5规范提出可相关解决方案

  1. 数据存储在用户浏览器中
  2. 设置,读取方便,甚至页面刷新不丢失数据
  3. 容量较大,sessionStorage和localStorage约5M左右

2 localStorage

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

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

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

  4. 存储数据 获取数据 删除数据

      //存储
            //localStorage.setItem('money',100)
            //获取
            //localStorage.getItem('money')
            //删除一个
            //localStorage.removeItem('money')
            //清空
            localStorage.clear()
    // 存储日期
          // localStorage.setItem("自定义",值-必须是字符串的格式)
          // localStorage.setItem("date","二〇二二年四月十五日 09:06:48")
    
          // 获取它
          const date=localStorage.getItem("date");
    	//删除它
    	localStorage.removeItem(key)
          console.log(date);
    

2 存储复杂数据类型存储

本地只能存储字符串,无法存储复杂数据类型,需要将复杂数据类型转换成JSON字符串,在存储到本地

JSON.stringify(复杂数据类型)

  1. 将复杂数据类型转换成JSON字符串 存储 本地存储中

JSON.parse(JSON字符串)

  1. 将JSON字符串转换成对象 取出 时候使用

      // 在行业中我们会这么做
          // // 1 还是正常定义对象
          // const obj = {
          //   name: '路飞',
          //   height: 100,
          //   weight: 200,
          // };
    
          // // 2 有好用的代码 ,可以帮我们快速把一个对象转成字符串
          // const objStr = JSON.stringify(obj);
    
          // // 3 本地存储 可以存储字符串类型的数据
          // localStorage.setItem("obj",objStr);
    
          // 4 把本地存储的数据重新读取出来
          // const newObjStr =  localStorage.getItem("obj");
          // // console.log(newObjStr);
    
          // // 5 你能不能帮 我 重新把 这个 字符串 解析成原来的对象 
          // const newObj = JSON.parse(newObjStr);
    
          // console.log(newObj);
    
          /* 
          1 本地存储无法存放 复杂类型的数据 
          2 复杂类型的数据 通过JSON对象  字符串 相互之间的转换 
           */
    
  2. 学生信息综合案例-存储image-20220416131737308

       <script>
          const strArr = localStorage.getItem('arr');
    
          // 1.1 定义数组 负责存放表格要显示的数据
          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 arrStr = JSON.stringify(arr)
            //存一份到本地存储中
            localStorage.setItem('arr',arrStr)
            // 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 arrStr = JSON.stringify(arr)
              //存一分到本地存储中
            localStorage.setItem('arr',arrStr)
              // 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>
    

拓展-元素属性

  1. 获取dom元素的固有属性,通过点语法来获取

     <a id="" href=""></a>
        <script>
            //获取dom元素的固有属性 通过点语法来获取
            const a = document.querySelector('a')
            //获取固有属性
            //a.href   a.id
        </script>
    
  2. 直接修改

     // 直接修改
          // a.href="http://www.qq.com";
          // a.id="top";
    
  3. 自定义属性 不能直接通过点语法来获取和设置

    <a data-index="0" id="nav" href="http://www.baidu.com" hello="no" aa="bb" >跳转</a >
     // 自定义属性 不能直接通过点语法来获取和设置
          // 获取 getAttribute("属性名")
          // console.log(a.hello);
          // console.log(a.aa);
          // console.log( a.getAttribute("hello") );
          // console.log( a.getAttribute("aa") );
    
  4. 设置 setAttribute(key,value)

     <a data-index="0" id="nav" href="http://www.baidu.com" hello="no" aa="bb" >跳转</a >
     // a.setAttribute("hello","123");
    
  5. 删除掉属性 removAttribute(key)

  6. 自定义属性 --> h5建议的自定义属性

    // 属性的时候 data-xxx 开头
          //  获取的时候  a.dataset.xxx
          //  设置  a.dataset.index = 3;
    
          // console.log(a.dataset.index);
          // a.dataset.index = 3;
    
  7. 小结

       /* 
          
          小结 
          标签的属性 有两种分为
          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 >
          */
        //  console.log( a.getAttribute("data-index") );
        //  console.log( a.getAttribute("id") );
        //  console.log( a.getAttribute("href") );
        //  console.log( a.getAttribute("hello") );
        //  console.log( a.getAttribute("aa") );
    
  8. 字符串方法

     // 我们在实际开发过程中,有很多需求要针对字符串做处理
          // js 帮我们封装了很多大量和实用 字符串方法
          // 先介绍一些
    
          // 转大写 转小写。
          // let msg = 'HELLODFDFDFDFDFD';
    
          // 广告 msg 大写
          // msg="HELLO";// 搞定  楼下大妈也会!!!  low 低级 不堪入目
          // console.log(msg.toUpperCase());
    
          // 转小写
          // console.log(msg.toLowerCase()); //转成小写
    
          // 字符串和数组很相似
          // 能不能把字符串 转成数组?
          const str="abcdefg"; //=> ["a","b","c","d","e","f","g"]
          // // split("")   分割
          // console.log(str.split(""));
          // const str = 'a-b-c-d-e-f-g'; // ["a","b","c","d","e","f","g"]
          // console.log(str.split('-'));
    
          // console.dir(str);
    
          /* 
          1 转大写  toUpperCase()
    
          2 转小写 toLowerCase()
    
          3 转数组 str.split('') 按照什么来分割你的字符串变成数组
           */
    
  9. 数组方法

     // 数组 补充 常用
          //
          // const arr = ['a', 'b', 'c', 'd'];
    
          // console.log(arr.join('')); // join 数组转字符串
          // console.log(arr.join('-')); // a-b-c-d 数组转字符串
    
          // 连接  数组和数组之间连接
          // const arr1 = ['1', '2', '3'];
          // const arr2 = ['a', 'b', 'c'];
          // 将两个数组合并成一个数组
          // console.log(arr1.concat(arr2));
    
          //字符串也有一个 concat 也是表示合并
          const str1 = '123';
          const str2 = 'abc';
          // console.log(str1.concat(str2));// 很少用  有什么用? 当你的键盘 + 键坏  使用它 
          console.log(str1 + str2); // 更加简单好理解
    

正则表达式

什么是正则表达式

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

语法

  1.   /* 
          正则的作用 寻找字符串  检测 这个字符串这有没有我想要的文字
           */
          const str = `金钱对你意味着什么?你有梦想吗?等等等等。一下子都让我陷入了沉思。真的需要好好的想想,然后写下来`;
       
          // 判断一下这个字符串中有没有 梦想 两个字
       
          // 定义规则
          const reg = /刘同学/;
       
          // 规则和字符串 匹配  test
          console.log(reg.test(str)); // 有 返回true 没有返回false
    
  2. 边界符说明
    ^表示匹配行首的文本(以谁开始)
    $表示匹配行尾的文本(以谁结束)

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

     const str = `金来123`;
          // const reg = /梦想/; // 只要字符串中 包含有 梦想  返回true
    
          // 你检测的字符串 必须要以 “梦” 开头  以 “想” 结尾
          //
          // const reg = /^金来$/; // 只能匹配 "金来"
          const reg = /^金来/; // `金来123`;
          // const reg = /金来$/; //  `1234323金来`; 
          // console.log(reg.test(str));
    
    
          /* 
          边界符 
          开头 ^ 
          结尾 $ 
           */
    
    
  3. 量词说明
    *重复零次或更多次
    +重复一次或更多次
    ?重复零次或者一次
    {n}重复N次
    {n,}重复N次或更多次
    {n,m}重复n到m次
     // 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>
    
  4. 字符类

    预定类说明
    \d匹配0-9之间的任一数字,相当于[0-9]
    \D匹配所有0-9以外的字符,相当于[^0-9 ]
    \w匹配任意的字母,数字和下划线,相当于[A-Za-z0-9_]
    \W除匹配任意的字母,数字和下划线,相当于[^A-Za-z0-9_]
    \s匹配空格(包括换行符,制表符,空格符等),相当于[\t\r\n\v\f]
    \S匹配非空格的字符,相当于[^\t\r\n\v\f]

    日期格式: ^\d{4}-\d{1,2}-\d{1,2}

    字符类1

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

    字符2

    // [ab]  => 可以匹配 a  或者 b
          // console.log(/[ab]/.test('a'));// 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
    

    测试正则

     // 注册账号  填写用户名 规则 必须是字母,范围 3-8
          // console.log(/[a-zA-Z]/);// 一个字母
          // console.log(/[a-zA-Z]/.test("a"));// true
          // 3-8
          // {3,8} 修饰前面[]
          // console.log(/[a-zA-Z]{3,8}/.test("ab"));// false
          // console.log(/[a-zA-Z]{3,8}/.test("abc"));// true
          // console.log(/[a-zA-Z]{3,8}/.test("111222 abc 333444"));// true
          // 边界符
          // console.log(/^[a-zA-Z]{3,8}$/.test("111222 abc 333444"));// false
          // console.log(/^[a-zA-Z]{3,8}$/.test("abc"));// true
    
          // 手机号码 验证  知道手机号码的验证规则 不懂去百度
          // 规则 以数字1开头 第二位数字可以是 35789  其他9位数字 (11位数组)
          // console.log( /^1[35789]\d{9}$/.test("dd")  );// false
          // console.log( /^1[35789]\d{9}$/.test("12345678901")  );// false
          // console.log( /^1[35789]\d{9}$/.test("13345678901"));// false
          // console.log( /^1[35789]\d{9}$/.test("15345678901"));// false
          // console.log( /^1[35789]\d{9}$/.test("17345678901"));// false
          // console.log( /^1[35789]\d{9}$/.test("18345678901"));// false
          // console.log( /^1[35789]\d{9}$/.test("19345678901"));// false
    
          // 邮箱  yeah123@dsfdf.com
          //  邮箱名称  yeah123   可以是字母或者数字  最少要有一个 {1,} 或者 +
          // 分隔符  @
          // 字母或者数字
          // 匹配一个.   => \.
          // 规定 com  com
    
          // console.log(/^[a-zA-Z0-9]+@[a-zA-Z0-9]+$/.test("yeah123@dsfdf"));// true
          // console.log(/^[a-zA-Z0-9]+@[a-zA-Z0-9]+$/.test("@dsfdf"));// false
          // console.log(/^[a-zA-Z0-9]+@[a-zA-Z0-9]+$/.test("sdfd@"));// false
          // console.log(/^[a-zA-Z0-9]+@[a-zA-Z0-9]+$/.test("sdfd@3"));// true
    
          // console.log(/./.test('a'));
          // 就想要表示. 本身   加一个反斜杠
          // console.log(/\./.test('a'));// false
          // console.log(/\./.test('.'));// true
          // console.log(/^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.com$/.test('sdfd@3')); // false
          // console.log(/^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.com$/.test('sdfd@3.com')); // true
    
          // 感受 代码不多 贼难! 
          // 
          // console.log(/^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.c(om|n)$/.test('sdfd@3.com')); // true
          // console.log(/^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.c(om|n)$/.test('sdfd@3.cn')); // true
          // c om
          // c n