zl程序教程

您现在的位置是:首页 >  前端

当前栏目

Web APIs第二天

Web 第二天 APIs
2023-06-13 09:17:40 时间

DOM-事件基础笔记

1. 能够给 DOM元素添加事件监听:

1. 什么是事件?
  1. 事件是在编程时系统内发生的动作或者发生的事情, 比如用户在网页上单击一个按钮
  2. 事件是在编程时系统内发生的动作或者发生的事情, 比如点击按钮 click
2. 什么是事件监听?

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

元素.addEventListener('事件', 执行的函数)
// 1. 事件监听 绑定事件/注册事件/事件侦听
// 程序检测是否有事件 如有事件触发 立即调用函数做出响应/注册事件
let num1 = document.querySelector('button')
// 事件源.addEvenTlistener('事件', 事件处理函数)
num1.addEventListener('click', function () {
      alert('您好')
})
3. 事件监听三要素:
  1. 事件源: 那个dom元素被事件触发了,要获取dom元素
  2. 事件: 用什么方式触发,比如鼠标单击 click、鼠标经过 mouseover 等
  3. 事件调用的函数: 要做什么事
  4. 事件类型要加引号
  5. 函数是点击之后再去执行,每次 点击都会执行一次
5. 淘宝点击关闭二维码
// 核心:利用样式的显示和隐藏完成, display:none 隐藏元素 display:block 显示元素
<div class="box">
    <img src="images/1.jpg">
    <i class="box1">x</i>
</div>
// 获取元素 i事件监听 触发函数/修改box样式
let num2 = document.querySelector('.box')
let num3 = document.querySelector('.box1')
num3.addEventListener('click', function () {
    num2.style.display = 'none'
})
6. 随机点名
// 需求:点击按钮之后,随机显示一个名字,如果没有显示则禁用按钮
<span>开始点名吧</span>
<button class="box2">点击开始点名</button>
function fn(min, max) {
    return Math.floor(Math.random() * (max - min + min) + min)
}
let num4 = document.querySelector('span')
let num5 = document.querySelector('.box2')
let num6 = ['赵云', '张飞', '马超']
// 按钮 事件监听
num5.addEventListener('click', function () {
    let num7 = fn(0, num6.length)
    num4.innerHTML = num6[num7]
    // 删除数组元素
    num6.splice(num7, 1)
    // 如果数组删没了 长度为0 就禁用按钮
    if (num6.length === 0) {
        num5.disabled = true
        num5.innerHTML = '已经抽完了'
    }
})
7. 随机点名案例
①点击开始按钮随机抽取数组的一个数据,放到页面中
②点击结束按钮删除数组当前抽取的一个数据
③当抽取到最后一个数据的时候,两个按钮同时禁用
// 核心:利用定时器快速展示,停止定时器结束展示
<h1>随机点名</h1>
<div class="box">
    <span>名字是:</span>
    <div class="name">这里显示姓名</div>
</div>
<div class="box1">
    <button class="start">开始</button>
    <button class="end">结束</button>
</div>
let arr = ['赵云', '张飞', '马超', '曹操']
function fn(min, max) {
    return Math.floor(Math.random() * (max - min + min) + min)
}
// 1.获取元素 div 两个按钮
let num1 = document.querySelector('.name')
let num2 = document.querySelector('.start')
let num3 = document.querySelector('.end')
// 2.num4/num5 是全局变量
let num4 = 0
let num5 = 0
// 3.给按钮注册事件
num2.addEventListener('click', function () {
    // 4.随机抽取数据 用定时器不断抽取
    num4 = setInterval(function () {
        num5 = fn(0, arr.length)
        num1.innerHTML = arr[num5]
    }, 30)
    // 6.删除到最后一个后 禁用按钮
    if (arr.length === 1) {
    num2.disabled = num3.disabled = true
}
})
// 5.结束按钮注册事件 就是停止开始定时器
num3.addEventListener('click', function () {
    clearInterval(num4)
    arr.splice(num5, 1)
})
8. 事件监听版本

DOM L0 : 事件源.on事件 = function() { }

DOM L2 : 事件源.addEventListener(事件, 事件处理函数)

发展史:

  1. DOM L0: 是DOM的发展的第一个版本; L:level
  2. DOM L1: DOM级别1 于1998年10月1日成为W3C推荐标准
  3. DOM L2: 使用addEventListener注册事件
  4. DOM L3: DOM3级事件模块在DOM2级事件的基础上重新定义了这些事件,也添加了一些新事件类型

2. 事件类型

1.鼠标事件/鼠标触发

  • click鼠标点击、mouseenter鼠标经过、mouseleave鼠标离开

2.焦点事件/表单获得光标

  • focus获得焦点、blur失去焦点

3.键盘事件/键盘触发

  • Keydown键盘按下触发、Keyup键盘抬起触发

4.文本事件/表单输入触发

  • input用户输入事件
1. 小米搜索框案例
①开始下拉菜单要进行隐藏
②表单获得焦点 focus,则显示下拉菜单,并且文本框变色(添加类)
③表单失去焦点,反向操作
//需求:当表单得到焦点,显示下拉菜单,失去焦点隐藏下来菜单
<div class="box">
    <input type="search" placeholder="小米笔记本">
    <ul class="box1">
        <li><a href="#">全部商品</a></li>
        <li><a href="#">小米11</a></li>
        <li><a href="#">小米10S</a></li>
    </ul>
</div>
let num1 = document.querySelector('input')
let num2 = document.querySelector('.box1')
// 2. 事件监听 获取光标 focus mouseenter
num1.addEventListener('focus', function () {
    // 3. 显示下拉菜单 文本框变色
    num2.style.display = 'block'
    num1.classList.add('search')
})
// 4. blur mouseleave 失去光标事件
num1.addEventListener('blur', function () {
    // 隐藏下拉 文本框去色
    num2.style.display = 'none'
    num1.classList.remove('search')
})
2. 微博输入案例
①判断用输入事件 input
②不断取得文本框里面的字符长度
③把获得数字给下面文本框
//需求:用户输入文字,可以计算用户输入的字数
<div class="w">
    <div class="box">
      <img src="images/tip.png" alt=""><br>
      <textarea placeholder="说点什么吧..." id="text" cols="30" rows="10" maxlength="200"></textarea>
      <div>
        <span class="box1">0</span>
        <span>/</span>
        <span>200</span>
        <button id="box2">发布</button>
      </div>
    </div>
    <div class="box3">
      <ul>
      </ul>
    </div>
  </div>
let num1 = document.querySelector('#text')
let num2 = document.querySelector('.box1')
// 1. 绑定事件 input 输入事件
num1.addEventListener('input', function () {
  // console.log(num1.value.length)
  // 2. 不断得到文本域里的文字长度
  num2.innerHTML = num1.value.length
})
3. 全选文本框案例
①全选复选框点击,可以得到当前按钮的 checked
②把下面所有的小复选框状态checked,改为和全选复选框一致
③如果当前处于选中状态,则把文字改为取消, 否则反之
//需求:用户点击全选,则下面复选框全部选择,取消全选则全部取消,文字对应变化
<table>
  <tr>
    <th class="box">
      <input type="checkbox" name="" id="checkall"><span class="all">全选</span>
    </th>
    <th>商品</th>
    <th>商家</th>
    <th>价格</th>
  </tr>
  <tr>
    <td>
      <input type="checkbox" name="check" class="ck">
    </td>
    <td>小米手机</td>
    <td>小米</td>
    <td>¥1999</td>
  </tr>
</table>
let num1 = document.querySelector('#checkall')
let num2 = document.querySelectorAll('.ck')
let num4 = document.querySelector('.all')
// 1. 事件监听 全选按钮
num1.addEventListener('click', function () {
  // 2. 把num1.checked 给下面三个ck小按钮
  // console.log(num1.checked)
  // 3. 三个ck按钮在伪数组里 用for遍历 依次给值
  for (let num3 = 0; num3 < num2.length; num3++) {
    // num2[num3].checked = true
    num2[num3].checked = num1.checked
  }
   // 4. 当全选按钮选中状态 则改为取消HTML
  if (num1.checked) {
    num4.innerHTML = '取消'
  } else {
    num4.innerHTML = '全选'
  }
})
// 5. 小按钮做法 给多个元素绑定相同事件
for (let num5 = 0; num5 < num2.length; num5++) {
  num2[num5].addEventListener('click', function () {
  // 6. 只要点击任何一个小按钮 都要遍历所有小按钮  
    for (let num6 = 0; num6 < num2.length; num6++) {
      // 看看选中没有 如果有false 则退出循环 结束函数
      if (num2[num6].checked === false) {
        num1.checked = false
        num4.innerHTML = '全选'
        return
      }
    }
    // 循环结束 代码走到这里 说明没false 都选中了 则全选按钮被选中
    num1.checked = true
    num4.innerHTML = '取消'
  })
}
4. 购物车加减操作
①给添加按钮注册点击事件, 获取表单的value,然后自增
②解除减号的disabled状态
③给减号按钮添加点击事件,获取表单的value,然后自减
④自减结束需要判断,如果结果小于等于1 则添加上disabled状态
//需求:用户点击加号,则文本框+1,点击减号,则文本框-1,如果文本框为1,则禁用减号
<div>
<input type="text" id="box" value="1" readonly>
<input type="button" value="+" id="box1">
<input type="button" value="-" id="box2" disabled>
<div class="box3">已经是最大数量了
</div>
let num1 = document.querySelector('#box')
let num2 = document.querySelector('#box1')
let num3 = document.querySelector('#box2')
let num4 = document.querySelector('.box3')
// 点击加号 事件监听
num2.addEventListener('click', function () {
  // 隐式转换
  num1.value++
  num3.disabled = false
  if (num1.value >= 10) {
    num2.disabled = true
    num4.style.display = 'block'
  }
})
// 点击减号 事件监听
num3.addEventListener("click", function () {
  num1.value--
  if (num1.value <= 1) {
    num3.disabled = true
  } else {
    num2.disabled = false
    num4.style.display = 'none'
  }
})

3. 高阶函数

高阶函数可以被简单理解为函数的高级应用,JavaScript 中函数可以被当成【值】来对待,基于这个特性实现函数的高 级应用

【值】就是 JavaScript 中的数据,如数值、字符串、布尔、对象等

1. 函数表达式

  1. 函数表达式和普通函数并无本质上的区别:
  2. 普通函数的声明与调用无顺序限制,推荐做法先声明再调用
  3. 函数表达式必须要先声明再调用
// 高阶函数 函数高级用法 把函数当值来看
// 1. 函数表达式
let num1 = 1
let num2 = function () {
    console.log(1)
}
// btn.onclick = function () {}

2. 回调函数

  1. 如果将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数
  2. 简单理解: 当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数
<button>点击</button>
function fn() {
    document.write('你好')
}
// 此时里面就是回调函数 回头去调用的函数
// setInterval(fn, 1000)
// 点击事件也是回调函数 当点击后回头调用
let num3 = document.querySelector('button')
num3.addEventListener('click', function () {
    alert('你好')
})

1. 函数表达式:

  1. 函数也是【数据】
  2. 把函数赋值给变量

2. 回调函数:

  1. 把函数当做另外一个函数的参数传递,这个函数就叫回调函数
  2. 回调函数本质还是函数,只不过把它当成参数使用
  3. 使用匿名函数做为回调函数比较常见

4. this环境对象

  1. 环境对象指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境
  2. 作用:弄清楚this的指向,可以让我们代码更简洁
  3. 函数的调用方式不同,this 指代的对象也不同
  4. 【谁调用, this 就是谁】 是判断 this 指向的粗略规则
  5. 直接调用函数,其实相当于是 window.函数,所以 this 指代 window
<button>点击</button>
function fn1() {
    console.log(this)
}
// fn1()
window.fn1()
let num4 = document.querySelector('button')
num4.addEventListener('click', function () {
    // num4 调用了函数 所以this指向num4
    console.log(this)
})

5. 编程思想

1.排他思想

  1. 当前元素为A状态,其他元素为B状态
  2. 干掉所有人, 使用for循环
  3. 复活他自己, 通过this或者下标找到自己或者对应的元素
<button class="pink">第1个</button><button>第2个</button><button>
let num1 = document.querySelectorAll('button')
for (let num2 = 0; num2 < num1.length; num2++) {
    num1[num2].addEventListener('click', function () {
        // this.classList.add('pink')

        // 1. for循环做法 干掉所有人
        // for (let num3 = 0; num3 < num1.length; num3++) {
        //     num1[num3].classList.remove('pink')
        // }

        // 2. 升级做法
        // 只需找出唯一的 pink类 删除
        document.querySelector('.pink').classList.remove('pink')

        this.classList.add('pink')
    })
}

6. Tab栏切换

①点击当前选项卡,当前添加类,其余的兄弟移除类, 排他思想
②下面模块盒子全部隐藏,当前的模块显示
//需求:点击不同的选项卡,底部可以显示 不同的内容
<div class="wrapper">
  <ul class="tab">
    <li class="tab-item active">国际大牌<span>◆</span></li>
    <li class="tab-item">国妆名牌<span>◆</span></li>
    <li class="tab-item">清洁用品<span>◆</span></li>
    <li class="tab-item">男士精品</li>
  </ul>
<div class="products">
    <div class="main active"><a href="###"><img src="images/guojidapai.jpg"></a></div>
    <div class="main"><a href="###"><img src="images/guozhuangmingpin.jpg"></a></div>
    <div class="main"><a href="###"><img src="images/qingjieyongpin.jpg"></a></div>
    <div class="main"><a href="###"><img src="images/nanshijingpin.jpg"></a></div>
  </div>
  </div>
let num1 = document.querySelectorAll('.tab .tab-item')
let num3 = document.querySelectorAll('.products .main')
// 1. 头部tab栏切换 给4个li添加点击事件
for (let num2 = 0; num2 < num1.length; num2++) {
    num1[num2].addEventListener('mouseenter', function () {
      // 2. 找到active类 移除掉 
        document.querySelector('.tab .active').classList.remove('active')
        // 3. this 当前的元素添加
        this.classList.add('active')

        // 4. 底部隐藏模块 要写在点击事件里
        document.querySelector('.products .active').classList.remove('active')
        // 5. div对应序号 加上active 
        num3[num2].classList.add('active')
    })
}
7. 点击随机显示图片
8. 同意协议按钮
9. 验证码倒计时
10. 显示隐藏密码