前端 - 笔记 - 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 - 事件
      • 当鼠标离开表单,并且表单值发生变化触发
相关推荐
胡西风_foxww8 分钟前
【ES6复习笔记】数值扩展(16)
前端·笔记·es6·扩展·数值
mosen86810 分钟前
uniapp中uni.scss如何引入页面内或生效
前端·uni-app·scss
白云~️10 分钟前
uniappX 移动端单行/多行文字隐藏显示省略号
开发语言·前端·javascript
沙尘暴炒饭12 分钟前
uniapp 前端解决精度丢失的问题 (后端返回分布式id)
前端·uni-app
昙鱼27 分钟前
springboot创建web项目
java·前端·spring boot·后端·spring·maven
天天进步201532 分钟前
Vue项目重构实践:如何构建可维护的企业级应用
前端·vue.js·重构
小华同学ai35 分钟前
vue-office:Star 4.2k,款支持多种Office文件预览的Vue组件库,一站式Office文件预览方案,真心不错
前端·javascript·vue.js·开源·github·office
APP 肖提莫37 分钟前
MyBatis-Plus分页拦截器,源码的重构(重构total总数的计算逻辑)
java·前端·算法
问道飞鱼1 小时前
【前端知识】强大的js动画组件anime.js
开发语言·前端·javascript·anime.js
k09331 小时前
vue中proxy代理配置(测试一)
前端·javascript·vue.js