前端 - 笔记 - JavaScript - WebAPI【DOM + 事件类型 + Date+ 节点操作 + window + 本地存储 + 正则表达式】

前言

  • Web API :是一套操作 网页内容(DOM)浏览器窗口(BOM)对象
    • API:就是一些预定义好的方法,这些方法可以实现特定的功能,开发人员可以直接使用;
    • Web API:浏览器提供了一套操作网页和浏览器的方法,通过这些方法可以轻松的操作元素和浏览器;
  • 复杂数据类型const 声明:复杂数据类型 放在 里面, 里面存放的 地址 指向 里面存放的 数据 的只是 里面存放的 数据 ,存放数据的 地址 不变
  • 变量名 ➡ 栈地址 ➡ 堆数据;
  • 解释:

const实际上指的并不是变量的值不得改动,

其实说的是变量指向的那个内存空间中保存的数据不得改变

简单数据类型是将值保存在栈中,所以用const声明简单数据类型时,值不得改变,相当于常量

而复杂数据类型是将引用地址保存在栈中,具体的值保存在堆中

那么用const声明复杂数据类型时,比如对象,数组时,只能保证的是这个地址是固定不变的

堆中保存的数据是不是可变的,就无法保证了

一、❗❗ DOM(文档对象模型)

  • Document Object Model --- 文档对象模型;
  • 定义:是HTML文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以在从程序中对该结构进行访问,从而改变文档的结构,样式和内容。DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将 web 页面和程序语言连接起来。进而操作网页的内容,实现各种功能和部分特效。

1.1 DOM树 和 DOM对象

1.1.1 DOM树

  • DOM树:一种树状结构,把页面标签按照树状结构排列好,结构更加清晰;
    • 每个DOM对象中都有表示层级关系的属性,利用这些属性把所有的DOM对象联系在一起,就形成一个树状结构,称为DOM树;
  • 作用:文档树直观的 体现了 标签与标签 之间 的 关系

1.1.2 DOM对象

  • DOM对象 : 浏览器根据htm标签自动生成的JS对象;
    • 浏览器把网页内容翻译成一个个的对象,把 网页内容 的 特征 翻译成 对象 的属性;
  • document对象:是DOM里提供的一个对象(DOM里面最大的对象
    • 它提供的属性和方法都是 用来访问操作 网页内容

1.2 获取DOM对象

  • 打印对象:打印元素的时候,以对象的形式展现

    js 复制代码
    console.dir(对象);

1.2.1 ❗❗ 根据CSS选择器来获取DOM元素

  • 1️⃣ 选择匹配的 第一个 元素
    • 语法

      js 复制代码
      document.querySelector('css选择器')
    • 代码展示:

      js 复制代码
      const li = document.querySelector('ul li')
    • 参数 :小括号里面 包含 一个 或 多个 有效的css选择器 字符串(引号)

    • 返回值

      • css选择器 匹配的 第一个元素 ,一个 HTMLElement 对象
      • ⚠ 如果 没有匹配 到元素就是 null
      • ⚠ 注意:必须加引号
  • 2️⃣ 选择匹配的 多个 元素
    • 语法

      js 复制代码
      document.querySelectorAll('css选择器')
    • 代码展示:

      js 复制代码
      const lis = document.querySelectorAll('li') //NodeList[li, li, li]
    • 参数 :小括号里面 包含 一个 或 多个 有效的CSS选择器 字符串

    • 返回值

      • CSS选择器匹配的 NodeList 对象集合
      • 如果页面 不存在 这个 元素 ,得到的就是一个 空的伪数组
      • 所有 匹配的 元素 放到 NodeList🟨伪数组🟨 里面 返回
      • 有长度,有索引
      • 没有push(),pop()等数组方法
      • 想要得到里面的每一个对象,则需要遍历获得
1.2.2 获取HTML、body、head、title
js 复制代码
document.documentElement	--- 	html
document.body			--- 	body
document.head			--- 	head			
document.title			--- 	title

1.2.3 ❌其他获取元素的方式

  • 1️⃣根据 id 获取元素
    *

    js 复制代码
    document.getElementById('id名称')
    • 注意:
      • id名称不加 #
  • 2️⃣根据 标签 获取 一类 元素
    *

    js 复制代码
    document.getElementsByTagName('标签名称')
    • 注意:
      • getElementsByTagName
      • 返回值:伪数组
  • 3️⃣根据 类名 获取元素
    *

    js 复制代码
    document.getElementsByClassName('类名')
    • 注意:
      • 类名不加 .
      • getElementsByClassName
      • 返回值:伪数组

1.3 操作元素内容

1.3.1 对象.innerText 属性

  • 元素 文本内容 添加/更新 到 任意标签 位置
  • 显示 纯文本不解析标签
  • 见代码展示

1.3.2 对象.innerHTML 属性

  • 元素内容 添加/更新 到任意标签位置

    • 包括标签、文本、注释
  • 会解析标签,多标签建议使用模板字符串

  • ⚠ 既要保留原来内容又要添加新内容,采用 字符串拼接 的方式
    *

    js 复制代码
    innerHTML += '要添加的文本'
  • 见代码展示
    代码展示

js 复制代码
<div class="box"> 天地不仁以万物为刍狗!!! </div>
<strong>
    const box = document.querySelector('.box') 
    // 对象.innerText 属性
    box.innerText = '扶我起来,我还能干!!!'
    box.innerText = '<strong>扶我起来,我还能干!!!</strong>'
  
    // 对象.innerHTML 属性
    box.innerHTML = '扶我起来,我还能干!!!'
    box.innerHTML = '<strong>扶我起来,我还能干!!!</strong>'
</strong>
  • innerText 和 innerHTML 的区别
    • innerText

      • 只能 获取 元素文本,无法 获取 标签
      • ⚠ 在获取文本的时候,包含 子元素 的 文本
    • innerHTML

      • 可以 获取对象里面的所有 文本+标签
    • 代码展示:

      js 复制代码
      <body>
          <div>
              123
              <p>456
              <span>789</span>
              </p>
          </div>
      
          <script>
              console.log(document.querySelector('div').innerText);
              console.log(document.querySelector('div').innerHTML);
          </script>
      </body>

1.3.3 获取表单元素文本

  • 语法: 元素.value
  • 获取 输入的字符长度元素.value.length
  • ⚠ 获取 button 的文本依然使用 innerHTML(button双标签)
  • 拓展:
    • 元素.value.trim() - 去除字符串 左右两侧 的空格

1.4 操作元素属性

1.4.1 操作 元素 属性

  • 语法元素.属性 = '值'
    • 代码展示:

      js 复制代码
      <img src="./images/1.webp" alt="">
      //随机数函数
      function getRandom(N, M) {
        return Math.floor(Math.random() * (M- N + 1)) + N
      }
      //获取图片对象
      //img在html中是标签,在js中是对象
      const pic = document.querySelector('img')
      // 修改对象的属性值
      pic.src = `./images/${getRandom(1, 6) }.webp`

1.4.2 控制 样式 属性

  • 1️⃣ 通过 style属性 操作css

    • 语法元素.style.样式属性 = '值'

      • 对于复杂的样式属性建议使用 小驼峰 命名法
      • 生成的是 行内样式表 ,权重很高,只有 !important 能做掉它
      • ⚠🔺 只写 属性
    • 代码展示:

      js 复制代码
      // 获取对象(元素)
      const box = document.querySelector('div')
      // 修改样式属性 对象.style.样式属性 = '值'
      box.style.width = '400px'
      box.style.height = '100px'
      box.style.backgroundColor = 'red'
      box.style['background-color'] = 'green'
  • 2️⃣ 通过 类名(className) 操作css

    • 语法:元素.className = '类名'

      • 注意:会覆盖前面的类名 新值换旧值
      • 想要原来的类名 -> 元素.className = '旧类名 新类名'
    • 代码展示:

      html 复制代码
      <style>
        div {
          width: 200px;
          height: 200px;
          background-color: pink;
        }
        .active {
          width: 300px;
          height: 300px;
          background-color: hotpink;
          margin-left: 100px;
        }
      </style>
      
      <body>
        <div class="one"></div>
        <script>
          // 1.获取元素
          // let box = document.querySelector('css选择器')
          let box = document.querySelector('div')
          // 2 给div添加类名 class 是个关键字,选用className替代它
          // 新值换旧值,会覆盖原来的类名
          box.className = 'active'
          // 用旧类名+新类名的形式覆盖原来的类名
          box.className = 'one active'
        </script>
      </body>
  • ❗3️⃣ 通过 classList 操作类 控制css

    • 语法

      • 追加 类:元素.classList.add('类名')
      • 删除 类:元素.classList.remove('类名')
      • 切换 类:元素.classList.toggle('类名')
        • 如果有这个类名就是删掉,没有就追加
      • 替换 类:元素.classList.replace('旧类名', '新类名')
        • 两个参数,第一个是原来的类名,第二个参数是替换的类名
      • 是否包含指定的 类:元素.classList.contains('类名')
        • 判断是否包含指定的类名,返回值是布尔值 true / false
    • ⚠ 注意:

      • 类名 不加 点,并且 是 字符串
      • 方法 ,注意加小括号
    • 代码展示:

      js 复制代码
      // 获取对象
      const box = document.querySelector('.one')
      
      // 追加类名
      box.classList.add('two')
      box.classList.add('three')
      
      // 删除类名
      box.classList.remove('three')
      
      // 切换类名
      // 如果有这个类名就是删除,没有就是追加
      box.classList.toggle('ab')
      box.classList.toggle('one')
      
      // 替换类名
      // 将 旧类名box 替换成 新类名box1
      box.classList.replace('box', 'box1')
      
      // 判断是否包含指定的类名
      console.log(box.classList.contains('box'))		// true
  • classList 和 className区别
    • classList追加类名 ,将新类名追加到旧类名后面,不影响以前的类名
    • className覆盖类名 ,新类名 覆盖 旧类名,影响以前的类名

1.4.3❗❗ 操作 表单元素 属性

  • 语法

    • 获取元素.属性名
    • 设置元素.属性名 = 新值
  • 代码展示:获取表单里面的值

    js 复制代码
    const input = document.querySelector('.computer')
    console.log(input.value)
    input.value = '扶我起来,我还能干!!!'
  • ⚠ 注意:对象.innerHTML 只能获取 普通元素文本 ,获取 表单元素文本 需要使用 对象.value

    • 注意: 对象.value 获得的文本是 包含 首尾空白符
      • 想要获得 有效的文本 需要使用 trim() 方法[对象.value.trim()],删除首尾的空白符
    • ⚠注意:获取 button 的文本还是用 innerHTML
  • 表单属性中添加就有效果,移除就没有效果,一律使用 布尔值 表示,如果为 true 代表 添加 了该 属性 ,如果是 false 代表 移除属性

    • disabled(禁用)、checked(选中)

    • 除了 ' 'false0nullundefinedNaN 其余的都是true,但是不建议写,建议写布尔值

    • 代码展示:

      js 复制代码
      <input type="checkbox" value="" name="">
      const input = document.querySelector('.computer')
      input.checked = true	// 让复选框选中
      input.checked = false	// 让复选框不选中
      input.disable = true	// 禁用吗? - 禁用(true)
      input.disable = false // 禁用吗? - 不禁用(false默认值)

1.4.4 ❗❗ 自定义属性

  • 属性
    • 标准属性:标签天生自带的属性,可以直接使用 点语法 操作

    • 自定义属性:

      • 在h5中推出了专门的 data- 自定义属性

      • 在标签上一律以 data- 开头(必须以 data- 开头)

      • 在DOM对象上一律以 dataset 对象方式获取

      • dataset 是一个 自定义属性集合包含 该标签内所有 自定义属性

      • 代码展示:

        html 复制代码
        <div data-id="1" data-spm="不知道">1</div>
        <div data-id="2">2</div>
        <div data-id="3">3</div>
        <div data-id="4">4</div>
        <div data-id="5">5</div>
        <script>
          // 获取元素
          const one = document.querySelector('div')
        	// one是一个HtmlElement对象
        	console.log(one)
        	// dataset是一个对象集合
        	console.log(one.dataset)
        	// 获取dataset对象里面的id属性
        	console.log(one.dataset.id)
        	// 获取dataset对象里面的spm属性
        	console.log(one.dataset.spm)
        </script>
  • ❌⛔ 拓展:
    • 获取自己 瞎定义的属性

    • 浏览器不会识别 瞎定义属性,并且它不会体现在DOM对象上

    • 语法:

      js 复制代码
      DOM对象.getAttribute(瞎定义属性名)

1.5 ❗❗ 定时器 - 间歇函数

  • 定时器 = setInterval() + setTimeout()
  • setInterval(函数, 间隔时间) (间歇函数):按照指定的周期(以毫秒计)来调用函数或计算表达式。方法会不停地调用函数,直到clearInterval()被调用或窗口关闭
    • 间歇函数可以根据时间自动重复执行某些代码
  • setTimeout(函数, 延迟时间)(延时函数):在指定的毫秒数后调用函数或计算表达式 (Timeout - 超出)
  • 定时器 里面的 第一个参数 是 回调函数
    • 将一个函数作为参数传递给另外一个函数,这个函数就是回调函数

1.5.1 开启定时器

  • 语法

    js 复制代码
    匿名函数:setInterval(函数, 间隔时间)		// Interval - 间隔,间隙
    具名函数:setInterval(函数名, 间隔时间)
  • 作用 :每隔一段时间 回头调用函数(先隔段时间 ,再调用函数)

    • 间隔时间 单位 是 毫秒(ms),不用写
    • 不是立即调用函数,时间间隔 过后再去 调用函数
  • 间歇函数返回值

    • 表示 当前定时器 是 页面中 的 第几个 定时器,是一个 id数字数字型)(唯一的)
    • 一个 间歇函数 只有 一个 返回值,并且是唯一
  • 代码展示:

    js 复制代码
    // 匿名函数
    setInterval(() => {
      console.log('扶我起来,我还能干!!!')
    }, 1000)
    
    // 具名函数
    function fn() {
      console.log('扶我起来,我还能干!!!')
    }
    setInterval(fn, 1000)
    // fn() --- 执行这个函数,只执行一次 (fn()调用这个函数)
    // fn --- 每隔一段时间,回头去找fn这个函数(自动调用),再执行(fn是一个变量,代表这个函数)
    
    // 定时器的返回值,是数字型,是id
    // 声明一个变量,接收定时器的返回值
    let n = setInterval(() => {
      console.log(1)
    }, 1000)
    console.log(n)			// 1
    
    function fn() {
      console.log('扶我起来,我还能干!!!')
    }
    let m = setInterval(fn, 1000)
    console.log(m)			// 2

1.5.2 关闭定时器

  • 语法

    js 复制代码
    // 匿名函数
    let 变量名 = setInterval(函数, 时间间隔)
    // 具名函数
    let 变量名 = setInterval(函数名, 时间间隔)
    clearInterval(变量)
  • 代码展示:

    js 复制代码
    // 匿名函数
    let n = setInterval(() => {
      console.log(11)
    }, 1000)
    
    // 具名函数
    function fn() {
      console.log('扶我起来,我还能干!!!')
    }
    let m = setInterval(fn, 1000)
    
    // 关闭定时器
    clearInterval(n)
    clearInterval(m)

二、❗❗ DOM事件基础

2.1 事件监听(绑定)

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

  • 事件监听三要素:

    • 事件源
    • 事件类型
    • 事件调用的函数(事件处理函数)
  • 语法

    js 复制代码
    元素对象.addEventListener('事件类型', 要执行的函数)
  • ⚠ 注意:事件类型 要加 引号

    • L2 注册的 事件 不会 出现 覆盖
    • L0 注册的事件会发生覆盖(后面的覆盖前面的)(同对象、同事件类型)
  • 代码展示:

    js 复制代码
    // 获取元素
    const btn = document.querySelector('button')
    // 事件监听-点击事件
    btn.addEventListener('click', () => {
      alert('扶我起来,我还能干!!!')
    })

2.2 事件类型

2.2.1 鼠标事件

  • 1️⃣ click - 鼠标点击
  • 2️⃣ mouseenter - 鼠标经过
  • 3️⃣ mouseleave - 鼠标离开
  • 4️⃣ mousemove - 鼠标移动
  • 5️⃣ dblclick - 鼠标左键双击

2.2.2 焦点事件

  • 1️⃣ focus - 获得焦点
  • 2️⃣ blur - 失去焦点

2.2.3 键盘事件

  • 1️⃣ keydown - 键盘按下触发
  • 2️⃣ keyup - 键盘抬起触发
  • 注意: 用鼠标粘贴内容不会触发

2.2.4 文本事件

  • 1️⃣ input - 用户输入事件
    • 获取用户 输入文本对象.value
    • 获取用户 输入文本长度对象.value.length
      • 注意:
        • 得到的 是 数字型
        • 包括 左右两侧 的 空格
    • 想要获得 有效文本和长度 (不包括首尾的空白符)
      • 有效文本: 对象.value.trim()
      • 有效长度: 对象.value.trim().length
      • trim() 方法:删除 字符串 首尾 空白符(空格、制表符、换行符等其他空白符)
      • 不会 改变 原始字符串
      • 不适用于null,undefined,Number类型

2.2.5 表单事件

  • 1️⃣ submit - 提交事件
  • 2️⃣ change - 失去焦点并且表单内容发生改变触发事件
  • 3️⃣ 重置表单: form.reset()

2.2.6 光标的坐标

  • 1️⃣ clientX 和 clientY
    • 光标距相对于 浏览器 可视化窗口 左上角 的位置
    • 鼠标在窗口中的位置
  • 2️⃣ pageX 和 pageY
    • 光标距离 文档流 左上角 的位置
    • 鼠标在页面中的坐标
    • 计算鼠标在某个盒子中的坐标:
      • 鼠标到盒子顶部的距离 = 鼠标到页面顶部的距离 - 盒子顶部到页面顶部的距离
      • 鼠标到盒子左侧的距离 = 鼠标到页面左侧的距离 - 盒子左侧到页面左侧的距离
  • 3️⃣ offsetX 和 offsetY
    • 光标距离 DOM元素 左上角 的位置
    • 鼠标在标签中的位置
  • ⚠🔺 拓展:利用 js 调用 事件
    • 语法:元素.事件类型()

2.3 事件对象 - event

  • 也是个对象,里面有事件触发时相关的信息

2.3.1 获取事件对象

  • ⚠ 使用场景:

    • 可以判断用户按下哪个键
    • 可以判断鼠标点击了哪个元素,从而做相应的操作
  • 语法:

    • 事件绑定回调函数第一个参数 就是 事件对象
    • 一般命名为 event、ev、e
    js 复制代码
    element.addEventListener('事件类型', function (e) {})
  • 在触发 DOM 上的某个事件时,会产生一个事件对象

  • event对象 包含与创建它的特定相关的和方法

2.3.2 事件对象常用属性

  • type获取 当前的 事件类型

  • clientX / clientY :获取 光标 相对于 浏览器可视化窗口 左上角 的位置

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

  • pageX / pageY : 光标距离 文档流 左上角 的位置

  • key

    • 用户 按下 键盘键的值
    • 现在不提倡使用keyCode
  • 代码展示:

    js 复制代码
    元素.addEventListener('click', function (e) {
      console.log(e.key)
      console.log(e.type)
    })

2.4 环境对象

  • 函数内部特殊的变量 this,代表当前函数运行时所处的环境
  • 每个函0数 里面 都有 this
  • 非严格模式
    • this指向函数的调用者(普通函数里面 this -> window)
    • 事件侦听里面,指向事件源
    • 箭头函数没有this(箭头函数不会自己创建this,它只会沿用自己所在这条作用域链的上层作用域的this)
    • 定时器里面this指向window

2.5 回调函数

  • 官方:如果将函数A作为参数传递给函数B时,我们称函数A为 回调函数
  • 把一个 函数 当作 参数 来 传递给 另外一个函数 的时候,这个函数就是 回调函数

三、❗❗ DOM事件进阶

3.1 事件流

3.1.1 事件流与两个阶段说明

  • 事件流 = 事件捕获 + 事件目标 + 事件冒泡
    • 事件流指的是:事件 完整 执行过程 中的 流动路径
    • 过程:事件捕获 => 事件目标阶段 => 事件冒泡 整个完整的过程就是事件流
  • 两个阶段:
    • 捕获阶段:从父到子(从大到小)
    • 冒泡阶段:从子到父(从小到大)
    • 实际工作中都是使用 事件冒泡 为主

3.1.2 ❌ 事件捕获(了解)

  • 概念:从DOM的 根元素 开始去执行对应的事件(从外到里)
  • 事件捕获需要写对应代码才能看见效果
    • 代码:

      js 复制代码
      DOM.addEventListener(事件类型, 事件处理函数[, 是否使用捕获机制 = false])
      • addEventListener第三个参数传入 true 代表是捕获阶段触发(很少使用)
      • 若传入false代表冒泡阶段触发,默认就是false
      • 若是用 L0(on事件类型) 事件监听,则只有冒泡阶段,没有捕获

3.1.3 事件冒泡

  • 从子到父(从小到大)

  • 概念:当一个元素触发事件后,会 依次 向上 调用 所有父级元素同名事件(同种事件类型)

  • 事件冒泡是默认存在的

  • 事件冒泡的必要性

    • 如果没有冒泡,给大盒子注册点击事件,点击的是里面的小盒子,会导致大盒子的点击无法执行
    • 事件委托(委托给祖先元素)
  • L2事件监听第三个参数是false,或者默认都是冒泡

  • 代码展示:

    js 复制代码
    const fa = document.querySelector('.father')
    const son = document.querySelector('.son')
    document.addEventListener('click', function () {
      alert('我是爷爷')
    })
    fa.addEventListener('click', function () {
      alert('我是爸爸')
    })
    son.addEventListener('click', function () {
      alert('我是儿子')
    })
    // 事件冒泡:从子到父
    // 弹出框的顺序依次是:儿子 -> 我是爸爸 -> 我是爷爷

3.1.4 阻止冒泡

  • 语法:

    js 复制代码
    事件对象.stopPropagation()		// 方法		停止传播		sp(快捷)
    e.stopPropagation()
    // 事件对象 - 回调函数的第一个参数
    • 此方法可以阻断事件流动传播 ,不光在冒泡阶段有效,捕获阶段也有效
  • 代码展示:

    js 复制代码
    const fa = document.querySelector('.father')
    const son = document.querySelector('.son')
    document.addEventListener('click', function () {
      alert('我是爷爷')
    })
    fa.addEventListener('click', function () {
      alert('我是爸爸')
    })
    son.addEventListener('click', function (e) {
      alert('我是儿子')
      // 阻止流动传播(阻止事件冒泡)
      // 在这一块卡住,不允许向上传播
      e.stopPropagation()
    })
    // 弹出框:我是儿子
  • 阻止元素默认行为:

    • 语法:

      js 复制代码
      e.preventDefault()		// 方法 阻止默认	pd(快捷)
      // 阻止 链接跳转
      // 阻止 表单提交(缺点:提交数据页面h)
    • 代码展示:

      html 复制代码
      <body>
        <form action="http://www.itcast.cn">
          <input type="submit" value="免费注册">
        </form>
        <a href="http://www.baidu.com">百度一下</a>
        <script>
          // 获取元素
          const a = document.querySelector('a')
          const form = document.querySelector('form')
          // 事件侦听-a-点击事件
          a.addEventListener('click', function (e) {
            // 阻止a的默认行为-页面跳转
            e.preventDefault()
          })
          // 事件侦听-form-提交事件
          form.addEventListener('submit', function (e) {
            // 阻止form的默认行为-表单的提交
            e.preventDefault()
          })
        </script>
      </body>

3.1.5 两种鼠标事件的区别

  • 注意:
    • mouseover 和 mouseout 会 有 冒泡效果
    • mouseenter 和 mouseleave 没有 冒泡效果(推荐)

3.1.6 解绑事件

  • 1️⃣ L0事件解绑(on方式)

    • 直接使用 null 覆盖就可以实现事件的解绑

    • 代码展示:

      js 复制代码
      btn.onclick = function () {
        alert('点击了')
      }
      // L0事件移除解绑
      btn.onclick = null
  • 2️⃣ L2 事件解绑

    • 语法:

      js 复制代码
      removeEventListener(事件类型, 函数名[, 获取捕获或冒泡阶段])
      • ⚠ 中括号包裹的参数可以省略
      • ⚠🔺 匿名函数 无法进行 事件解绑 操作
      • ⚠ 解绑的时候必须是 同一个函数(两个函数体一样 的 匿名函数 不是 同一个函数)
    • 代码展示:

      js 复制代码
      <script>
        // 获取元素
        const btn = document.querySelector('button')
      	// 声明函数
      	let fn = function (e) {
                  alert(`事件解绑语法:
                  元素.removeEventListener(事件类型, 函数名)
                  匿名函数 无法进行 事件解绑 操作
                  ${e.target.tagName}
                `)
              }
      	// 事件侦听-点击事件
      	btn.addEventListener('click', fn)
      	// 事件解绑
      	btn.removeEventListener('click', fn)
      </script>

3.1.7 两种注册事件的区别

  • 1️⃣ 传统on 注册(L0)
    • 同一个对象,后面注册的事件会 覆盖 前面注册的事件(同一个事件
    • 直接使用 null 覆盖就可以实现事件的解绑
    • 都是 冒泡阶段 执行的(只有冒泡没有捕获)
  • 2️⃣ 事件监听 注册(L2)
    • 语法:addEventListener(事件类型, 事件处理函数[ , 是否使用捕获 = false])
      • 既能捕获也能冒泡
      • 捕获 将第三个参数 改成 true
      • 冒泡不用写,默认就是冒泡(false)
    • 后面注册的事件 不会覆盖 前面注册的事件(同一个事件
    • 可以通过 第三个参数 去确定是在 冒泡阶段 或者 捕获阶段 执行的
    • 必须使用 removeEventListener(事件类型, 事件处理函数[ , 获取捕获或者冒泡阶段])
    • ⚠🔺 匿名函数无法解绑

3.2 事件委托

  • 优点:

    • 减少注册次数
    • 提高程序性能
    • ⚠ 为未来元素预备事件(添加节点)
  • 原理: 事件委托其实是利用 事件冒泡 的特点

    • 父元素 注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件
  • 注意: 事件触发元素嵌套关系很复杂就不可以使用事件委托

  • 实现:

    • 获得 真正 触发事件 的 元素(对象):事件对象.target
    • 获得 真正 触发事件元素 的 标签名称:事件对象.target.tagName
  • 代码展示:

    html 复制代码
    <body>
      <ul>
          <li>第1个孩子</li>
          <li>第2个孩子</li>
          <li>第3个孩子</li>
          <li>第4个孩子</li>
          <li>第5个孩子</li>
          <p>我不需要变色</p>
      </ul>
      <script>
          // 1.点击每个小li,当前li文字变色
          // 按照事件委托的方式,委托给父级,事件写到父级身上
          // 获取元素
          const ul = document.querySelector('ul')
          // 事件绑定
          ul.addEventListener('click', function (e) {
              // e:事件对象
              // 得到一个事件对象
              // console.log(e)
              // 得到被点击的元素
              // console.log(e.target)
              // 得到被点击元素的标签名称
              // 得到的标签名称是 大写的 字符串
              // console.log(e.target.tagName)	// 'LI'
              // 判断点击的是不是li,如果是li文字就变颜色
              if (e.target.tagName === 'LI') {
                  e.target.style.color = 'red'
              }
          })
      </script>
    </body>

3.3 其他事件

3.3.1 页面加载事件

  • ⚠ JavaScript 写在body上面,必须 使用 load 事件 或者 DOMContentLoaded事件
  • 1️⃣ load 事件
    • 等待页面 所有外部资源(外联CSS、外联JavaScript,图片......) 加载完毕 时,就回去执行回调函数
    • 事件名: load(等待)
    • 监听 整个页面 所有外部资源 加载完毕
      • ⚠ 给 window 添加 load 事件

      • 语法:

        js 复制代码
        window.addEventListener('load', function () {
          //	执行操作
        })
      • 代码展示:script标签在body标签上方

        js 复制代码
        <script>
          // 给 window 添加 页面加载事件(load)
          window.addEventListener('load', function () {
          // 获取元素
          const btn = document.querySelector('button')
          // 事件侦听-点击事件
          btn.addEventListener('click', function () {
            alert(`
               页面加载事件
               给 window 添加 load 事件
               window.addEventListener('load', function() {})
              `)
          })
        })
        </script>
        <body>
          <button>点击</button>
        </body>
      • ⚠ 注意:不光可以监听整个页面资源加载完毕,也可以针对某个资源绑定 load事件

  • 2️⃣ DOMContentLoaded 事件
    • 初始的HTML文档(DOM节点) 被完全加载和解析完成之后,DOMContentLoaded事件被触发,而无需等待外部资源加载
    • 事件名: DOMContentLoaded
    • 监听页面 DOM节点 加载完毕
      • ⚠ 给 document 添加 DOMContentLoaded 事件

      • 语法:

        js 复制代码
        document.addEventListener('DOMContentLoaded', function () {
          // 执行的操作
        })
      • 代码展示:

        js 复制代码
        document.addEventListener('DOMContentLoaded', function () {
          // 获取元素
          const btn = document.querySelector('button')
          // 事件侦听-点击事件
          btn.addEventListener('click', function () {
            alert(`
                页面加载事件
                给 document 添加 DOMContentLoaded 事件
                document.addEventListener('DOMContentLoaded', function() {})
              `)
          })
        })

3.3.2 元素滚动事件 - scroll

  • 滚动条 滚动的时候 触发(⚠ 页面 必须有 滚动条 才能 触发

    • 让 页面 具有 滑动效果 (不是瞬间到指定位置,而是缓慢滑动到指定位置)
      *

      css 复制代码
      /* 页面滑动 */
      html {
        /* 让滚动条丝滑的滑动 */
        /* 滚动-行为:平滑 */
        scroll-behavior: smooth;
      }
  • 让 html标签(页面最大的标签) 滚动
    *

    js 复制代码
    document.documentElement.scrollTop // html被卷去的高度
    window.pageYoffset		// 页面滚出去的高度(页面在竖轴的偏移量)
    document.documentElement.scrollTop === window.pageYoffset
  • 应用场景:固定导航栏、返回顶部

  • 事件名: scroll

  • 监听 整个页面 滚动

    • 语法:

      js 复制代码
      window.addEventListener('scroll', function () {
        // 执行的操作
      })
    • ⚠ 注意:

      • 给 window(常用) 或 document 添加 scroll 事件
      • 监听 某个元素的内部 滚动 直接给 某个元素 加即可
    • 代码展示:

  • 获取位置

    • scrollTop (被卷去的头部) 和 scrollLeft (被卷去的左侧) (属性)

      • ⚠🔺 读写属性(可以 读取 亦可以 赋值)

      • ⚠ 获取到的是 数字 ,赋值的时候 不带单位

      • 检测页面滚动的头部距离
        *

        js 复制代码
        document.documentElement.scrollTop = 数字
        js 复制代码
        window.pageYoffset - 只读属性
      • 获取 被卷去 的大小

      • 获取 元素内容 往左、往上滚出去 看不到距离

      • ⚠ 得到的是:数字型 不带单位

      • 尽量写在 scroll事件 里面

      • 代码展示:

      html 复制代码
      <style>
        * {
          margin: 0;
          padding: 0;
          box-sizing: border-box;
        }
      
        body {
          height: 3000px;
        }
      
        div {
          display: none;
          margin: 100px auto;
          width: 470px;
          height: 150px;
          border: 1px solid #000;
          text-align: center;
          font-size: 20px;
          font-family: '隶书';
        }
      
        .active {
          display: block;
          position: fixed;
          top: 0;
          left: 50%;
          transform: translateX(-50%);
          margin-top: 0;
        }
      </style>
      
      <body>
        <div>
          世间的悲喜皆不如我所愿,但苦于乐皆是恩赐!!!
          世间的悲喜皆不如我所愿,但苦于乐皆是恩赐!!!
          世间的悲喜皆不如我所愿,但苦于乐皆是恩赐!!!
          世间的悲喜皆不如我所愿,但苦于乐皆是恩赐!!!
          世间的悲喜皆不如我所愿,但苦于乐皆是恩赐!!!
          世间的悲喜皆不如我所愿,但苦于乐皆是恩赐!!!
        </div>
        <script>
          // 事件侦听-页面滚动事件-window
          window.addEventListener('scroll', function () {
            // 获取html元素
            const html = document.documentElement
            // 获取div元素
            const div = document.querySelector('div')
            // console.log(html.scrollTop);		// 得到的是数字型
            // scrollTop >= 300显示div并固定在可视区域顶部,小于300隐藏
            if (html.scrollTop >= 300) {
              div.classList.add('active')
            } else {
              div.classList.remove('active')
            }
          })
        </script>
      </body>
    • 让页面 滚动到指定位置

      • 1️⃣ 属性赋值

        js 复制代码
        document.documentElement.scrollTop = 指定位置距离顶部的距离
      • 2️⃣ 方法

        window.scrollTo(x, y)
        

3.3.3 ❌ 页面尺寸事件 - resize(了解)

  • 窗口尺寸改变 的时候 触发事件

    • 事件类型: resize

    • 语法:

      js 复制代码
      window.addEventListener('resize', function () {
        // 执行的代码
      })
  • 检测屏幕宽度

    • 语法:

      js 复制代码
      window.addEventListener('resize', function () {
        let w = document.documentElement.clientWidth
        console.log(w)
      })
  • 获取元素宽高 (属性)

    • 获取元素的 可见部分 宽高(不包含border、margin、滚动条)
    • clientWidthclientHeight
    • 得到的是 数字型

3.4 ❗❗ 元素的尺寸和位置

  • 1️⃣ 获取 宽高: (属性)

    • 获取元素 自身的宽高
      • 内容 + padding + border
    • offsetWidthoffsetHeight
    • 获取到的是 数值
    • ⚠ 获取的是 可视宽高,如果盒子是隐藏的,获取的结果是0
  • 2️⃣ 🔻 获取 位置:

    • ① 获取元素 距离自己 最近一级 定位 祖先元素左、上 距离
      • 带有 定位属性 的 祖先元素
      • 如果都没有,就以文档左上角为准
    • offsetLeftoffsetTop
      • 相对于 页面 来说
      • 只读属性
    • 获取的是可视宽高,若盒子隐藏,则获得的是0
    • ② ❌ 元素.getBoundingClientRect() (了解)
      • 返回元素的 大小 及其 相对于视口的位置

      • 相对于 视口

      • 代码展示:

        js 复制代码
        const div = document.querySelector('div')
        div.getBoundingClientRect()

总结

属性 作用 说明
scrollLeftscrollTop 卷去头部左侧 配合 页面滚动(scroll 事件) 来用,可读写
clientWidthclientHeight 获得 元素宽度高度 不包含border、margin、滚动条,用于js 获取元素大小 只读属性
offsetWidthoffsetHeight 获得 元素宽度高度 包含border、padding、滚动条等,只读属性
offsetLeftoffsetTop 获取元素距离 自己定位父元素 的左、上距离 获取 元素位置 的时候使用,只读属性
  • scroll系列 、 client系列 、 offset系列
    • scroll系列: 标签内部 内容 的大小,位置
      • scrollTop / scrollLeft:表示标签真实内容相对于标签的位置
      • ❌scrollWidth / scrollHeight:表示标签真实内容的大小(和标签本身的大小无关,是内容的宽高)
    • client系列: 标签 容纳范围(border里面) 的大小、位置
      • clientWidth / clientHeight:表示标签内容区域的大小
      • ❌clientTop / clientLeft:表示标签内容区域的位置(几乎不用,仅仅表示上边框的高度,左边框的宽度)
    • ✔🔻 offset系列: 标签本身 的大小、位置
      • offsetWidth / offsetHeight:包含content + padding + border
      • offsetTop / offsetLeft:最近一级带有定位属性祖先元素 的 相对位置(如果没有定位,那么就是相对于body)
  • 拓展:
    • 添加css让页面滚动平滑
      *

      css 复制代码
      html {
        scroll-behavior: smooth;
      }
    • if单分支语句拓展:
      *

      js 复制代码
      if (old) old.classList.remove('active')
      js 复制代码
      old && old.classList.remove('active') - 逻辑与
      js 复制代码
      old?.classList.remove('active') - 可选链
    • 属性选择器
      *

      js 复制代码
      document.querySelector('[data-name=new]')
      自定义属性 的 属性值 可以 省略 双引号(不推荐)

四、❗❗ 日期对象

  • 用来 表示时间 的 对象
  • 作用: 得到 当前系统时间
  • 日期对象:Date构造函数的实例,记录了一个时间信息

4.1 实例化

  • 实例化 :有 new 关键字的都是实例化(见 JS 高级)

4.1.1 得到当前时间

  • 创建一个 时间对象 并 获取时间
    • 语法:

      js 复制代码
      const 常量名 = new Date()
    • 代码展示:

      js 复制代码
      const date = new Date()
      console.log(date)
      // Wed Aug 03 2022 20:37:52 GMT+0800 (中国标准时间)
      // 周三 八月 3号 年份 时间 

4.1.2 指定时间

  • 倒计时 的时候 使用

  • 语法:

    js 复制代码
    const 常量名 = new Date('指定的时间')
  • 参数:

    • 数字 : 月份是从 0 开始的
    • 字符串 : 月份是正常的
  • 代码展示:

    js 复制代码
    const date = new Date('2022-8-3 20:50:00')
    let h = date.getHours()
    console.log(h)	// number
    console.log(date)
    console.log(typeof date)	// object
    // Wed Aug 03 2022 20:50:00 GMT+0800 (中国标准时间)

4.2 日期对象方法

语法 作用 说明
对象.getFullYear() 获得 年份 获取 四位 年份
对象.getMonth() 获得 月份 取值为 0 ~ 11
对象.getDate() 获取 月份中的 某一天 不同月份取值不同
对象.getDay() 获取 星期 取值为 0 ~ 6
对象.getHours() 获取 小时 取值为 0 ~ 23
对象.getMinutes() 获取 分钟 取值为 0 ~ 56
对象.getSeconds() 获取 取值为 0 ~ 59
对象.getMilliseconds() 获取 毫秒 取值为 0~1000
  • 注意:
    • 周日是一周的开始 -> 周日 = 0
    • 当前月份 = 获取的月份 + 1
    • ⚠ 得到的都是 数字型

4.3 时间的另一种写法

  • 时间对象.toLocaleString() :年月日时分秒

  • 时间对象.toLocaleDateString() :年月日

  • 时间对象.toLocaleTimeString() :时分秒

  • 代码展示:

    js 复制代码
    // 获得当前系统时间
    const systemTime = new Date()
    // 从 获取的当前系统时间(systemTime)里找
    // 获取年份
    const year = systemTime.getFullYear()
    // 获得月份
    const month = systemTime.getMonth() + 1
    // 获取月份中的某一天
    const date = systemTime.getDate()
    // 获取星期
    const day = systemTime.getDay()
    // 获取小时
    const hours = systemTime.getHours()
    // 获取分钟
    const minutes = systemTime.getMinutes()
    // 获取秒
    const seconds = systemTime.getSeconds()
    console.log(systemTime);
    console.log(`${year} 年 ${month} 月 ${date} 日 周${day}  ${hours} 时 ${minutes} 分 ${seconds} 秒`)
    // Wed Aug 03 2022 21:14:56 GMT+0800 (中国标准时间)
    // 2022 年 8 月 3 日 周3  21 时 14 分 56 秒
  • 格式化时间:

    html 复制代码
    <!DOCTYPE html>
      <html lang="en">
    
       <head>
       <meta charset="UTF-8">
       <meta http-equiv="X-UA-Compatible" content="IE=edge">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <title>Document</title>
    <style>
     * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    	}
    
    	div {
      	margin: 100px auto;
      	width: 600px;
      	height: 100px;
      	border: 5px solid #969696;
      	background-color: #d7d7d7;
      	color: hsl(338, 100%, 50%);
      	font-size: 44px;
      	font-weight: 700;
      	font-family: '华文隶书';
      	text-align: center;
      	line-height: 100px;
    	}
    </style>
    </head>
    
    <body>
      <div></div>
      <script>
          // 写法一:  
      	const div = document.querySelector('div')
              function getTime() {
                  const date = new Date()
                  let hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
                  let minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
                  let seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
                  return `当前时间:${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} 	${hours}:${minutes}:${seconds}`
              }
              
              div.innerHTML = getTime()
              setInterval(function () {
                   div.innerHTML = getTime()
              }, 1000)
              // 当前时间:2022-8-3 22:45:50
    
              // 写法二:自动补0
              /*
                  // 定时器外面再写一次的原因:定时器隔1s再去执行,用外面的填补页面空白
                  div.innerHTML = date.toLocaleString()
                  // div.innerHTML = date.toLocaleDateString()
                  // div.innerHTML = date.toLocaleTimeString()
                  setInterval(function () {
                      const date = new Date()
                      div.innerHTML = date.toLocaleString()	 // 2022/8/3 23:00:00
                      // div.innerHTML = date.toLocaleDateString()    // 2022/8/3
                      // div.innerHTML = date.toLocaleTimeString()    // 22:48:20
                  }, 1000)
              */
      </script>
    </body>
    </html>

4.3 时间戳

  • 使用场景:倒计时

  • 时间戳: 是指1970年01月01日00时00分00秒起 至现在毫秒数

  • 注意:

    • 时间戳唯一的

    • ⚠ 中国 在 东8区

      js 复制代码
      const date = +new Date('1970-01-01 00:00:00') / 1000 / 60 / 60
      console.log(date)	// -8
  • ⚠🔻 算法

    • 将来的时间戳 - 当前的时间戳 = 剩余时间毫秒数

    • 剩余时间毫秒数 转换为 剩余时间的 日时分秒 就是 倒计时

    • 展示:

      将来时间戳 2000ms - 现在时间戳 1000ms = 1000ms
      1000ms 转换时分秒就是 0小时0分1秒
      
  • 三种获取时间戳的方法:

    • 1️⃣ 使用 getTime() 方法

      • 语法:

        js 复制代码
        const date = new Date()
        console.log(date.getTime())	// 1659539589145 毫秒数
        // new Date().get.Time()
        拓展:
        时间对象.getTime() 和 时间对象.valueOf() 的到的结果一样
        console.log(date.getTime() === date.valueOf())	// true
      • 注意:

        • 必须 先 实例化
        • ⚠ 可以返回 指定时间的时间戳
    • 2️⃣ ✔简写 +new Date()

      • 语法:

        js 复制代码
        console.log(+new Date())  // 1659539732765 毫秒数
      • 注意:

        • + -> 正号 (隐式转换)
        • ⚠ 可以返回 指定时间的时间戳
          • 代码展示:

            js 复制代码
            conlose.log(+new Date('2022-10-1 07:30:00'))
            // 1664580600000 -- 指定时间的时间戳
    • 3️⃣ 使用 Date.now()

      • 语法:

        js 复制代码
        console.log(Date.now())  // 1659540040487 毫秒数
      • 注意:

        • 没有 实例化
        • ⚠ 只能得到 当前的 时间戳
  • 时间转换公式

    • 通过 时间戳 得到是 毫秒,需要转换为秒在计算
    • 转换公式:
      • days: d = parseInt(总秒数 / 60 / 60 / 24)
      • hours: h = parseInt(总秒数 / 60 / 60 % 24)
      • minutes: m = parseInt(总秒数 / 60 % 60)
      • seconds: s = parseInt(总秒数 % 60)
  • 倒计时函数:

    js 复制代码
    const element = document.qurySelector('css选择器')
    function getCountTime(time) {
      // 得到当前的时间戳(毫秒)
      const now = +new Date()
      // 得到未来时间时间戳(毫秒)
      const last = +new Date(time)
      // 得到剩余的时间戳(毫秒) 并转换为 秒
      const count = (last - now) / 1000
      // 将 剩余秒数 -> 天、时、分、秒
      let day = parseInt(count / 60 / 60 / 24)
      let hours = parseInt(count / 60 /60 % 24)
      // 补0
      hours = hours < 10 ? '0' + hours : hours
      let minutes = parseInt(count / 60 % 60)
      // 补0
      minutes = minutes < 10 ? '0' + minutes : minutes
      let seconds = parseInt(count % 60)
      // 补0
      seconds = seconds < 10 ? '0' + seconds : seconds
      return `${day} 天 - ${hours}:${minutes}:${seconds}`
    }
    
    function getRemainingTime(element, time) {
      // 先执行一次:定时器过1s再去执行,会有1s的显示空白时间,让它限制性,填补空白,再让后面的覆盖
      element.innerHTML = getCountTime(time)
      setInterval(function () {
          element.innerHTML = getCountTime(time)
          }, 1000)
    }
    
    getRemainingTime(div, '2022-10-1 00:00:00')

五、❗❗ 节点操作

  • 浏览器 使用 对象记录 网页内容
    • 浏览器把网页内容翻译成一个个的对象,把 网页内容 的 特征 翻译成 对象 的 属性
    • 这个对象就称为 DOM对象
    • 网页内容的特征:
      • 标签属性
      • 标签内容
      • 标签上下级
      • ...
  • 网页内容 、对象
    • 网页内容: 标签、文本、注释
    • DOM对象:标签(元素)节点、文本节点、注释节点
    • 网页内容 和 DOM对象 一 一 对应
  • DOM树
    • 每个DOM对象中都有表示层级关系的属性,这些属性把所有DOM对象联系在一起,形成一个树状结构,称为DOM树
    • DOM树 === 网页

5.1 DOM节点

  • DOM节点: DOM树 里面 每一个内容 都称之为 节点
  • 节点类型:
    • 1️⃣ ❗✔元素节点:
      • 所有的 标签
      • html根节点
    • 2️⃣ 属性节点:
      • 所有的属性
    • 3️⃣ 文本节点:
      • 所有的文本

5.2 查找节点 - 属性

  • 有效返回值 是一个 对象
  • 无效返回值 - null

5.2.1 父节点

  • 1️⃣ parentNode 属性
    • 语法:

      js 复制代码
      子元素.parentNode
    • 返回值:

      • DOM对象
      • 最近一级 的父节点(亲爸爸),找不到 返回 null
    • 代码展示:

      js 复制代码
      <div class="yeye">
          <div class="dad">
              <div class="baby">x</div>
          </div>
      </div>
      
      <script>
          const baby = document.querySelector('.baby')
          console.dir(bady)		// div.bady -> DOM对象
          console.dir(baby.parentNode)	// div.dad -> DOM对象
          console.dir(baby.parentNode.parentNode)	  // div.yeye -> DOM对象
      </script>
    • 关闭广告:

      html 复制代码
      <!DOCTYPE html>
      <html lang="en">
      
      <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
          .box {
            position: relative;
            width: 1000px;
            height: 200px;
            background-color: pink;
            margin: 100px auto;
            text-align: center;
            font-size: 50px;
            line-height: 200px;
            font-weight: 700;
          }
      
          .box1 {
            position: absolute;
            right: 20px;
            top: 10px;
            width: 20px;
            height: 20px;
            background-color: skyblue;
            text-align: center;
            line-height: 20px;
            font-size: 16px;
            cursor: pointer;
          }
        </style>
      </head>
      
      <body>
        <div class="box">
          我是广告
          <div class="box1">X</div>
        </div>
        <div class="box">
          我是广告
          <div class="box1">X</div>
        </div>
        <div class="box">
          我是广告
          <div class="box1">X</div>
        </div>
      
        <script>
          // const smallBox = document.querySelectorAll('.box1')
          /* for (let i = 0; i < smallBox.length; i++) {
            smallBox[i].addEventListener('click', function () {
              this.parentNode.style.display = 'none'
            })
          } */
      
          // 事件委托
          document.body.addEventListener('click', function (e) {
            if (e.target.className === 'box1') {
              e.target.parentNode.style.display = 'none'
            }
          })
        </script>
      </body>
      
      </html>

5.2.2 子节点

  • 1️⃣ ❌childNodes 属性
    • 语法:

      js 复制代码
      父元素.childNodes
    • 返回值: 获得 所有子节点 、包括文本节点(空格、行换)、注释节点等

  • 2️⃣ ⚠🔻 children 属性
    • 语法:

      js 复制代码
      父元素.children
    • ⚠ 返回值: 伪数组 (要想得到里面的每一个节点还是要遍历

    • 注意:

      • 仅获得 所有 元素节点(标签)
      • 只选亲儿子,只不过是把亲儿子里面包含的所有节点(元素、文本、注释...)拿过来
    • 代码展示:

      js 复制代码
      <ul>
         <li>
              1
              <p>6</p>
              <span>7</span>
          </li>
          <li>2</li>
          <li>3</li>
          <li>4</li>
          <li>5</li>
      </ul>
      
      <script>
        // 获取子节点
        // 语法:父元素.children
        // 返回值:伪数组
        // 仅 获得 所有 元素节点(标签)
        console.log(document.querySelector('ul').children);
      	// 得到的是一个伪数组
      </script>

5.2.3 兄弟节点

  • 1️⃣ 下一个 兄弟节点

    • nextElementSibling 属性

    • 语法:

      js 复制代码
      兄弟元素.nextElementSibling
    • 返回值:

      • 有下一个兄弟节点,得到的就是下一个元素
      • 没有 就是 null
  • 2️⃣ 上一个 兄弟节点

    • previousElementSibling 属性

    • 语法:

      js 复制代码
      兄弟元素.previousElementSibling
    • 返回值:

      • 有上一个兄弟节点,得到就是上一个元素
      • 没有 就是 null
  • 代码展示:

    js 复制代码
    <ul>
      <li>
          1
          <p>6</p>
          <span>7</span>
      </li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
    </ul>
    
    <script>
      // 上一个兄弟节点
      // 语法:兄弟元素.previousElementSibling
      // 下一个兄弟节点
      // 语法:兄弟元素.nextElementSibling
      console.log(document.querySelector('ul li:nth-child(2)').nextElementSibling)
    </script>

5.3 增加节点

  • 创建 追加

5.3.1 创建节点

  • 语法:

    js 复制代码
    document.createElement('标签名')		// 文档.创建元素
    • 创建的节点是一个正常的DOM对象

    • ⚠ 注意:

      js 复制代码
      document.createElement()  --  创建的是空标签

5.3.2 追加节点

  • 1️⃣ 插入到 父元素最后一个 子元素

    • 语法:

      js 复制代码
      父元素.appendChild(要插入的元素)	// 追加孩子
    • 注意: 做为 父元素 里面最后一个 子元素

    • 代码展示:⬇

  • 2️⃣ 插入到 父元素某个子元素前面

    • 语法:

      js 复制代码
      父元素.insertBefore(要插入的元素, 在哪个元素前面)	// 插入在...之前
    • 注意: 插入到 父元素 里面指定位置

    • 代码展示:⬇

  • 注意: appendChildinsertBefore 如果插入的是页面上 已经存在 的标签,会有 剪切 效果(将已经存在的元素 从 原位置 剪切到 新位置)

  • 代码展示:

    html 复制代码
    <style>
        div,
        li {
          font-size: 20px;
          text-align: center;
          line-height: 50px;
        }
    
        li:first-child {
          width: 150px;
          height: 50px;
          background-color: #b8f0e8;
        }
    
        li:last-child {
          width: 150px;
          height: 50px;
          background-color: #a6a6db;
        }
    
        div {
          width: 150px;
          height: 50px;
          background-color: #c0bfbf;
        }
    </style>
    
    <body>
      <ul>
        <li>我是老大</li>
      </ul>
    
      <script>
        // 增加节点(节点 -> 元素节点)
        //  1.创建节点
        //    语法:document.createElement('标签名称')
        //  2.插入节点
        //    (1).作为父元素里面的最后一个子元素
        //        语法:父元素.appendChild(要插入的元素)
        //    (2).插入到父元素里面指定位置(插入到父元素里面某个子元素的前面)
        //        语法:父元素.insertBefore(要插入的元素, 在那个子元素前面)
    
        // 1.创建节点
        const li = document.createElement('li')
        li.innerHTML = '我是老二'
        // 2.插入节点
        //    2.1获取父元素
        const ul = document.querySelector('ul')
        //    2.2作为父元素里面的最后一个子元素
        ul.appendChild(li)
    
        // 1.创建节点
        const div = document.createElement('div')
        div.innerHTML = '我是老大的大哥'
        // 2.插入节点
        //    2.1获取父元素
        const body = document.body
        //    2.2插入到父元素指定位置(插入到父元素里面指定元素前面)
        body.insertBefore(div, ul)
        // 将创建的节点始终插入到父元素的最前面
        /*
          body.children  // 包含body下所有的(亲)子节点伪数组
        	body.insertBefore(div, body.children[0])
        */
      </script>
    </body>

5.3.3 克隆节点

  • 特殊情况 的 新增节点

  • 应用场景:轮播图

  • 步骤:

    • 1️⃣ 复制 一个 原有节点
    • 2️⃣ 把 复制的节点 放入到 指定元素内部
  • 语法:

    js 复制代码
    元素.cloneNode(布尔值)
    • clondNode会克隆出一个跟原标签一样的标签(原标签上面有什么,克隆后的标签上面就有什么)(是两个元素,克隆成功后前后两个元素没有任何关系)

    • 参数:

      • true - 深克隆: 克隆时 包含 后代节点 一起克隆 (节点 -> 文本节点、注释节点等所有的节点)
      • false - 浅克隆: 克隆时 不包含 后代节点、
      • 默认值false
    • 代码展示:

      js 复制代码
      <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
      </ul>
      
      <script>
          const ul = document.querySelector('ul')
          // const newLi = ul.children[0].cloneNode(true)
          // newLi.innerHTML = 'newLi'
          // ul.appendChild(newLi)
          ul.insertBefore(ul.children[0].cloneNode(true), ul.children[11])
      </script>

5.4 删除节点

  • 在 JavaScript 原生DOM操作中,要 删除元素 ⚠ 必须 通过 父元素 删除

  • 语法:

    js 复制代码
    父元素.removeChild(要删除的元素)
  • 注意:

    • 如果 不存在 父子关系 则 删除 不成功
    • 删除节点 和 隐藏节点(display: none;)有区别
      • 删除节点:从DOM中删除节点
      • 隐藏节点:只是在页面上不显示,DOM节点依然存在
  • 补充:

    • 语法: 自杀式z

      js 复制代码
      删除的元素.remove()
  • 拓展:

    • 替换节点:

    • 语法:

      js 复制代码
      parentNode.replaceChild(newChild, oldChild);
    • 方法用指定的节点替换当前节点的一个子节点,并返回被替换掉的节点

  • 重绘 和 回流

    • 重绘: 由于节点(元素)样式的改变并不会影响它在文档流中的位置和文档布局时,则是重绘
    • 回流: 元素的尺寸、结构、布局等发生变化时,浏览器就会重新渲染部分或全部文档的过程称为回流
    • 重绘不一定一起回流,但回流一定会引起重绘
    • 简单理解,影响到了布局,就会有回流

六、❌ M端事件

  • 常见的触屏事件(touch)
触屏 touch 事件 说明
touchstart 手指 触摸 到一个DOM元素时触发
touchmove 手指在一个DOM元素上 滑动 时触发
touchend 手指从一个DOM元素上 移开 时触发

七、❗ JS插件

八、❗❗ window对象

window(JS中的顶级对象) > BOM(浏览器对象模型) > DOM(页面文档对象模型)

8.1 BOM(浏览器对象模型)

  • BOM (Browser Object Model)- 浏览器对象模型
    • 由一些列相关的对象构成,并且每个对象都提供了很多方法和属性
    • 浏览器的内容被翻译成了对象
  • window 对象是一个 全局对象 ,也可以说是 JavaScript 中的 顶级对象
  • 像document、alert()、console.log()这些都是window的属性,基本BOM的属性和方法都是window的
  • ⚠ 所有通过 var 定义在 全局作用域 中的 变量函数 都会变成 window对象属性方法
  • ⚠ window对象下的属性和方法调用的时候可以 省略window
  • DOM 和 BOM 区别:

8.2 定时器 - 延时函数

  • 定时器 = 间歇函数(setInterval()) + 延时函数(setTimeout())

  • 让代码 延迟 执行的函数 - setTimeout()

  • 语法:

    js 复制代码
    setTimeout(回调函数, 等待的毫秒数)
  • 清除延时函数:

    js 复制代码
    let timerId = serTimeout(回调函数, 等待的毫秒数)
    clearTimeout(timerId)
  • 注意:

    • setTimeout 仅仅 只执行 一次 ,平时省略 window
    • 延时函数需要等待,所以后面的代码先执行
    • 每一次调用延时器都会 产生一个 新的 延时器
  • 间歇函数 和 延时函数 的区别:

    • 间歇函数:每隔一段时间就执行一次,除非手动清除
    • 延时函数:执行一次

8.3 JS执行机制

  • JS代码 从上到下 执行
  • 单线程: 同一时间只能做一件事
    • 所有的任务需要排队,前一个任务结束,才会执行后一个任务

8.3.1 同步 与 异步

  • 1️⃣ 同步
    • 前一个任务结束后再执行后一个任务,程序的执行顺序任务的排列顺序一致的
    • 同步任务: 都在 主线程 执行栈 上执行
  • 2️⃣ 异步
    • 如果执行一个任务需要花费一定的时间,在执行这个任务的同时可以去执行别的任务
    • 耗时 的都是 异步
    • JS的 异步 是通过 回调函数 实现的
    • 异步任务的三种类型
      • 普通事件(click、mouseenter、mouseleave、......)
      • 资源加载
      • 定时器 (间歇函数(setInterval) + 延时函数(setTimeout))
    • 异步任务 添加到 任务队列 (消息队列)中
  • 同步异步本质 区别:
    • 一条流水线上的 各个流程 执行顺序不同
  • 3️⃣ 执行机制:
    • ① 先执行 任务栈 中的 同步任务
    • 异步任务 添加到 任务队列 里面
      • 异步任务 进行 排序(根据每个异步任务所消耗的时间 )
    • ③ 一旦 执行栈 里面的 所有 同步任务 执行完毕系统 就会 按次序 读取 任务队列 中的 异步任务 ,于是 被读取异步任务 结束 等待状态进入 执行栈,开始执行。

8.3.2 事件循环 - event loop

  • 由于 主线程 不断的 重复 获得任务、执行任务、再获取任务、再执行,所以这种机制被称为 事件循环(enevt loop)
  • 事件循环: js执行代码时,会把同步任务添加到主线程执行栈中执行,把满足条件的异步任务推到任务队列排队等候执行,事件循环是一种轮询机制,当执行栈中的所有同步任务执行完毕之后,系统就会依次读取任务队列中的异步任务,异步任务结束等待状态,按照次序添加到执行栈中执行。

8.4 location 对象

  • location数据类型对象 ,它 拆分保存URL地址各个 组成 部分
  • 常用 属性 和 方法:
    • 1️⃣ ✔🔺 href: 属性 获取 完整的URL地址 ,对其 赋值时 用于 地址的跳转
      *

      js 复制代码
      const btn = document.querySelector('button');
      btn.addEventListener('click', function () {
          location.href = 'https://www.baidu.com';
      });
      • 可以后退
    • 2️⃣ search: 属性 获取地址中 携带的参数 ,符号 ? 后面部分
      *

      js 复制代码
      console.log(location.search); 	// 字符串
    • 3️⃣ hash: 属性 获取地址中的 哈希值 ,符号 # 后面部分
      *

      js 复制代码
      console.log(location.hash);		// 字符串
    • 4️⃣ reload(是否使用缓存): 方法 用来 刷新 当前 新页面,传入参数 true 时表示 强制刷新 ,默认false使用缓存刷新
      *

      js 复制代码
      const btn = document.querySelector('.reload');
      btn.addEventListener('click', function () {
        // F5 -> 刷新
        //location.reload();
        // F5+Ctrl -> 强制刷新  
        location.reload(true);
      });
    • 5️⃣ replace(): 方法 页面跳转(覆盖旧地址)
      *

      js 复制代码
      const btn = document.querySelector('button');
      btn.addEventListener('click', function () {
          location.replace('https://www.baidu.com');
      });
    • href属性replace()方法 实现页面跳转的区别:

      • href属性: 保留 原地址具有回退功能
      • replace()方法: 覆盖 原地址没有回退功能
  • navigator数据类型对象 ,该对象记录了 浏览器 自身的 相关信息
  • 常用 属性 和 方法:
    • 浏览器相关信息:navigator.userAgent

    • 通过 userAgent 检测 浏览器版本平台

      js 复制代码
      // 检测userAgent(浏览器信息)
      !(function () {
        const userAgent = navigator.userAgent;
        // 验证是否为Android或iPhone
        const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/);
        const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/);
        // 如果是Android或iPhone,则跳转至移动站点
        if (android || iphone) {
          location.href = 'http://m.itcast.cn';
        }
      })();

8.6 history 对象

  • histroy数据类型对象,主要管理历史记录,该对象与浏览器地址栏的操作相对应。
  • 常用属性和方法:
    • back(): 可以 后退 功能

    • forward(): 前进 功能

    • go(参数): 前进 后退 功能

      • 参数:
        • 1: 前进 一个页面 (back())
        • 0: 刷新页面(使用缓存刷新) (reload())
        • -1: 后退 一个页面 (forward())
    • 代码展示:

      html 复制代码
      <button>后退</button>
      <button>前进</button>
      <script>
          // 获取元素
          const back = document.querySelector('button');
          const forward = back.nextElementSibling;
          // 事件侦听-点击事件
          back.addEventListener('click', function () {
          // 前进一步
          history.go(1);
          });
          forward.addEventListener('click', function () {
          // 后退一步
          history.go(-1);
          });
      </script>

九、❗❗ 本地存储

  • 数据存储 在 用户 浏览器 中(硬盘)
  • 设置、读取方便、甚至 页面刷新 不会丢失 数据
  • 容量较大、sessionStprangelocalStorage 约5M
  • 为什么要将数据存储到本地存储里?
    • 数据持久化(数据不丢失)

9.1 本地存储分类

9.1.1 localStorage

  • 作用: 可以 将 数据 永久存储本地 (用户电脑),除非手动清除 ,否则关闭页面 也会 存在
  • 生命周期: 什么时候失效,什么时候死掉
  • 特性:
    • 可以多窗口(页面)共享同一浏览器 可以共享)(不能跨域(同一个域名)使用)
    • 键值对 的形式 存储使用
  • ⚠🔻 语法:
    • 1️⃣ 存储/修改 数据:

      js 复制代码
      localStorage.setItem(key, value)		
      // 设置每个小项,key和value要加引号,key和value可以是变量
      • 这个键就是 修改没有 就是 添加

      • 代码展示:

        js 复制代码
        // 本地存储 - localStorage
        // 存储数据 - localStorage.setItem(key, value);
        // 要加引号
        localStorage.setItem('uname', '邵秋华');
    • 2️⃣ 获取 数据:

      js 复制代码
      localStorage.getItem(key)			// 获取里面的项,key必须加引号
      • 返回值:

        • 有这个key,就返回对应的值
        • 没有这个key,返回 null
      • 代码展示:

        js 复制代码
        // 获取数据 - localStorage.getItem(key)
        // 要加引号
        console.log(localStorage.getItem('uname'));	// 邵秋华
    • 3️⃣ 删除 某项数据:

      js 复制代码
      localStorage.removeItem(key)		// 移除里面的项, key必须加引号
      • 代码展示:

        js 复制代码
        // 删除本地存储
        localStorage.removeItem('uname');
    • 4️⃣ 清空 数据:

      js 复制代码
      localStorage.clear()
      • 慎用
      • 清空全部数据
  • ⚠⚠ 注意:
    • ⚠ 所有的 必须加 引号

    • 有这个键就是修改,没有就是添加

    • ⚠🔺 本地存储 只能存储 字符串 类型的数据

    • 得到的值也是字符串型

    • 如果value写的是数值型,存的时候会转换成字符型

    • 代码展示:

      js 复制代码
      const arr = [1, 2, 3, 4];
      arr.forEach((item, index) => {
        localStorage.setItem(`id:${index}`, item);
        console.log(localStorage.getItem(`id:${index}`));	// 1 2 3 4(字符串)
        console.log(typeof (localStorage.getItem(`id:${index}`)));// string
      });

9.1.2 sessionStprange

  • 特性:
    • 生命周期关闭浏览器窗口
    • 同一个窗口 (页面)下 数据可以共享
    • 键值对 的形式 使用
    • 用法跟localStorage基本相同
  • localStoragesessionStorage 的区别
    • 他们的 作用 相同 ,但是 存储方式 不同,因此应用场景也不同
    • localStorage 的数据可以 长期存储关闭浏览器 数据不会消失,除非 手动清除
    • sessionStorage 的数据时是 临时存储页面被关闭 ,存储在sessionStorage里的 数据 会被 清除

9.2 存储复杂数据类型

  • 本地存储 只能存储 字符串,不能存储 复杂数据类型
  • JSON:
    • 属性和值都有引号,而且是双引号
    • 一种字符串格式的名称
    • 把 数组/对象 转换为结构为 "数组/对象" 的字符串
    • 只能存:数字、字符串、对项
    • 不能存null、undefined、函数
    • ⚠ JSON.parse(转换数据):要转换的数据不是JSON格式的字符串
  • 存储复杂数据类型步骤:
    • 1️⃣ 将 复杂数据类型JSON字符串
      • 语法:

        js 复制代码
        JSON.stringify(复杂数据类型)
      • 代码展示:

        js 复制代码
        // 本地存储只能存储字符串,不能存储复杂数据类型
        // 如果要存储复杂数据类型,需要将复杂数据类型转换成 JSON 字符串
        // 语法:JSON.stringify(复杂数据类型);
        let obj = {
          uname: '邵秋华',
          age: 22,
          gender: '男',
        };
        
        localStorage.setItem('obj', JSON.stringify(obj));
    • 2️⃣ 将 JSON字符串复杂数据类型
      • 语法:

        js 复制代码
        JSON.parse(JSON字符串)
      • 代码展示:

        js 复制代码
        console.log(JSON.parse(localStorage.getItem('obj')));
  • 存:
    • 复杂数据类型 -> JSON.stringify() -> JSON字符串 -> 存到本地存储中
  • 取:
    • 从本地存储中取 -> JSON字符串 -> JSON.parse() -> 复杂数据类型

十、❗ 正则表达式

  • 正则表达式 (Reular Expression):用于 匹配 🔺字符串 🔺 中 字符组合模式
    • JavaScript 中,正则表达式 也是 对象(object )
    • ⚠🔺 注意: 只能对 字符串 进行匹配
  • 正则表达式的作用
    • 1️⃣ 表单验证(匹配
    • 2️⃣ 过滤敏感词汇(替换
    • 3️⃣ 字符串中提取我们想要的部分(提取 ->-爬虫)

10.1 正则表达式的使用

  • 1️⃣ 定义规则:

    • 语法:

      js 复制代码
      const regObj = /表达式/	// 正则表达式不改变使用
      js 复制代码
      const regObj = new RegExp('表达式')	// 正则表达式变化使用
    • 注意:

      • // 正则表达式 的 字面量
      • // 中间写什么,就查找什么
      • ⚠🔺 // 中间 不要乱加 空格
      • 只要涉及到正则表达式不要乱加空格,最好用vs格式化
  • 2️⃣ ✔检测查找是否匹配:

    • 语法:

      • test() :用来 查看 正则表达式指定的字符串 是否匹配
      js 复制代码
      regObj.test(被检测的字符串)
    • 返回值:

      • 匹配true
      • 不匹配false
      • 规则在前面,被检测的就是用户输入的内容
    • 注意:

  • 代码展示:

    js 复制代码
    // 正则表达式
    // 正则表达式使用
    // 1)定义规则
    //    语法:const 变量名(regObj) = /表达式/;
    //    注意:正则表达式的字面量中间 不要乱加空格
    //    字面量中间些什么就匹配什么(不要乱加空格)
    // 2)是否匹配
    //    语法:regObj(字面量).test(被检测的字符串);
    	const reg = /前端/;
    	const str = '我在学习前端,希望学完高薪就业!!!';
    	console.log(reg.test(str));		// true
    
    // 注意
    	const reg = / 前端 /;
    	const str = '我在学习前端,希望学完高薪就业!!!';
    	console.log(reg.test(str));		// false
    
    // 注意
    	console.log(/哈/.test('哈'));		// true
    	console.log(/哈/.test('哈哈'));	// true
    	console.log(/哈/.test('二哈'));	// true
  • 3️⃣ ⭕检索符合规则的字符串:

    • 语法:

      • exec() :在一个 指定字符串 中执行一个 搜索匹配
      js 复制代码
      regObj.exec(被检测字符串)
    • 返回值:

      • 匹配数组
      • 不匹配null
  • 代码展示:

    js 复制代码
    const reg = /前端/;
    const str = '我在学习前端,希望学完高薪就业!!!';
    console.log(reg.exec(str));	
  • 正则表达式检测查找 test()方法 和 exec()方法 有什么区别?

    • text(): 用于判断是否有符合规则的字符串,返回的是一个布尔值,找到 返回 true没找到 返回 false
    • exec(): 用于检索(查找)符合规格的字符串,找到 返回 数组没找到null

10.2 ❗ 元字符

  • 字符

    • 普通字符
      • 大多数的字符仅能够描述它们本身(字母数字)
      • 普通字符 只能够 匹配 字符串中 与 它们 相同的字符
    • 元字符
      • 是一些 具有 特殊含义 的 字符
      • 优点: 极大提高了 灵活性 和 强大的匹配功能
  • ⚠🔻 边界符、量词、字符类 组合使用

  • 1️⃣ 边界符

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

    • 用来提示字符所处的位置
      *

      边界符 说明
      ^ 表示匹配 行首 的文本(以谁开始
      $ 表示匹配 行尾 的文本(以谁结束
      • 注意:

        • ^ $ 在一起,表示 必须是 精确匹配
      • 代码展示:

        js 复制代码
        console.log(/哈/.test('哈'));		// true	// 字符串的内容 和 规则相等
        console.log(/哈/.test('哈哈'));	// true
        console.log(/哈/.test('二哈'));	// true
        
        console.log(/^哈/.test('哈'));	// true
        console.log(/^哈/.test('哈哈'));	// true
        console.log(/^哈/.test('二哈'));	// flase
        
        console.log(/^哈$/.test('哈'));	   // true
        console.log(/^哈$/.test('哈哈'));  // false -- 精确匹配(字符串的内容、长度必须和规则相等)
        console.log(/^哈$/.test('二哈'));  // flase
  • 2️⃣ 量词

    • 表示重复次数
    • 设定 某个模式出现 次数
    量词 说明
    ***** 重复 零次多次 >= 0
    + 重复 一次多次 >=1
    ? 重复 零次一次
    {n} 重复 n次
    {n,} 重复 n次更多次 >= n
    {n,m} 重复 n 到 m 次 n <= 次数 <= m
    • ⚠🔺注意:
      • 🔺n,m🔻 之间 🔺没有空格🔻
      • 离量词 最近的(量词的左边) 重复,别的不重复
  • 3️⃣ 字符类

    • [] - 匹配字符集合

      • 被检测的数据 只要能和 规则 匹配到 任意🔺一个🔻字符 就是 true,否则就是false

      • 代码展示:

        js 复制代码
        后面的字符串只要包含abc中任意一个字符,都返回true
        console.log(/[abc]/.test('andy'));  // true
        console.log(/[abc]/.test('baby'));  // true
        console.log(/[abc]/.test('cry'));   // true
        console.log(/[abc]/.test('die'));   // false
      • 精确匹配: 被检测的数据 🔺只能 🔻 和 规则 匹配 🔺一个🔻 字符 (n选1),要想多个匹配须和量词配合使用

        js 复制代码
        console.log(/^[abc]$/.test('a'));	  // true
        console.log(/^[abc]$/.test('b'));	  // true
        console.log(/^[abc]$/.test('c'));	  // true
        console.log(/^[abc]$/.test('ab'));	// false
        console.log(/^[abc]{1,}$/.test('abc'));	// true
    • - 连字符

      • 使用连字符 - 表示一个 范围
      • [a-z] : 表示 a~z 26个英文字母都可以
      • [a-zA-Z] : 表示大小写都可以
      • [0-9] : 表示 0~9 都可以
      js 复制代码
      [\u4e00-\u9fa5] 匹配汉字
      • 代码展示:

        js 复制代码
        /^[1-9][0-9]{4,}$/	// 第一个数字:1~9;从第二位开始:0~9;可以重复>=4
    • ^ - 取反符号

      • [] 加上 ^ 取反符号
      • [^a-z] :匹配除了小写字母以外的字符
      • 注意: 写到 [] 里面
    • . 匹配 除了换行符之外的任何单位

    • 预定义类 :某些常见模式的简写方法
      *

      预定义 说明
      \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]
      ```js
      日期:^\d{4}-\d{1,2}-\d{1,2}$
      ```
      
    • () 使用小括号将字符包成一个整体

    • |

  • 特殊符号 写到 [] 里的最后面

10.3 修饰符

  • 修饰符 约束 正则表达式的某细节 行为 ,如是否区分大小写、是否支持多行匹配

  • 语法:

    js 复制代码
    /表达式/修饰符
    • i: (ignore)正则匹配时 不区分 大小写
    • g: (global)匹配 所有 满足正则表达式结果 (全局匹配)
    • m: 执行多行匹配
    • 代码展示:⬇
  • replace - 替换

    • 语法:

      js 复制代码
      字符串.replace(/正则表达式/, '替换文本')
    • 返回值: 替换好的字符串

    • 代码展示:⬇

    • 替换多个:

      js 复制代码
      字符串.replace(/正则表达式/g, '替换文本')
      • 代码展示:⬇
    • 替换多个 并且 不区分大小写:

      js 复制代码
      字符串.replace(/正则表达式/ig, '替换文本')
      字符串.replace(/正则表达式/gi, '替换文本')
      • ⚠🔺 g i 不区分 前后
      • 代码展示:⬇
    • 替换多个 并且 不区分大小写: (用正则表达式里面的

      js 复制代码
      字符串.replace(/正则表达式|正则表达式/, '替换文本')
      • ⚠🔺 或(|) 两侧 不要加 空格
      • 如果没有小括号,就是将正则表达式分成多份
      • 代码展示:⬇
    • 代码展示:

      js 复制代码
      // 修饰符:约束正则表达式的细节行为
      // 语法: /正则表达式/修饰符
      // i(不区分大小写) + g(匹配所有满足正则表达式的结果)
      // i
      console.log(/^java$/.test('JAVA'));   // false
      console.log(/^java$/i.test('JAVA'));  // true
      console.log(/^java$/i.test('JavA'));  // true
      
      // 替换 - replace
      // 语法:字符串.replace(/正则表达式/, '替换文本')
      const str = 'java是一门编程语言,学完JAVA工资很高';
      
      // 替换一个
      const re1 = str.replace(/java/, '前端');
      console.log(re1);		// '前端是一门编程语言,学完JAVA工资很高'
      
      // 替换多个 - g
      const re2 = str.replace(/java/ig, '前端');
      console.log(re2);		// '前端是一门编程语言,学完前端工资很高'
      
      // 替换多个 - 或(|) (正则表达式里的或)(|两侧不要加空格)
      const re3 = str.replace(/java|JAVA/g, '前端');
      console.log(re3);		// '前端是一门编程语言,学完前端工资很高'
  • 拓展:

    • change - 事件
      • 当鼠标离开表单,并且表单值发生变化触发
相关推荐
Red Red5 分钟前
网安基础知识|IDS入侵检测系统|IPS入侵防御系统|堡垒机|VPN|EDR|CC防御|云安全-VDC/VPC|安全服务
网络·笔记·学习·安全·web安全
IT女孩儿42 分钟前
CSS查缺补漏(补充上一条)
前端·css
贰十六1 小时前
笔记:Centos Nginx Jdk Mysql OpenOffce KkFile Minio安装部署
笔记·nginx·centos
知兀1 小时前
Java的方法、基本和引用数据类型
java·笔记·黑马程序员
吃杠碰小鸡2 小时前
commitlint校验git提交信息
前端
醉陌离2 小时前
渗透测试笔记——shodan(4)
笔记
虾球xz2 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇2 小时前
HTML常用表格与标签
前端·html
LateBloomer7772 小时前
FreeRTOS——信号量
笔记·stm32·学习·freertos
疯狂的沙粒2 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript