2. DOM 事件基础 - 注册事件、tab 栏切换(1)之事件监听、随机点名案例、事件类型及实例

1. 事件监听

事件 是在编程时系统内发生的 动作 或者发生的 事情 ,例如用户在网页上 点击 了一个注册按钮,这就是一个 点击事件

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

DOM 事件监听三要素:

示例:

HTML 复制代码
  <body>
    <button>点击有惊喜哦~</button>

    <script>
      let btn = document.querySelector('button')

      btn.addEventListener('click', () => {
        alert('月薪过万')
      })
    </script>
  </body>

注意:

  • 事件类型要 加引号
  • 函数是点击之后再去执行的,每次点击都会执行一次

实例1:点击按钮,关闭二维码

分析:

  • 首先 获取 按钮元素和父盒子元素
  • 点击 的是按钮元素,关闭 的是父盒子
  • 利用 元素样式 的显示/隐藏属性来完成,写法多样,以下示例其中一种
HTML 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JS 事件</title>
    <style>
      .code {
        position: relative;
        margin: 50px auto;
        width: 800px;
      }
      img {
        position: absolute;
        width: 430px;
        height: 435px;
        border: 1px solid #000;
        margin-left: 10px;
      }
      .display {
        display: none;
      }
    </style>
  </head>

  <body>
    <div class="code">
      <button>X</button>
      <img src="./code.png" alt="" />
    </div>

    <script>
      let btn = document.querySelector('button')
      let code = document.querySelector('.code')

      btn.addEventListener('click', () => {
        code.className = 'display'
      })
    </script>
  </body>
</html>

实例2:随机点名

分析:

  • 首先 获取 按钮元素,点击的是按钮
  • 随机 抽取一个名字
  • 名字抽取完毕,利用 元素样式 禁用按钮
HTML 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JS 事件</title>
    <style>
      .box {
        position: relative;
        margin: 50px auto;
        width: 500px;
        height: 200px;
        border: 1px solid #000;
      }
      .box-name {
        margin: 30px auto;
        width: 260px;
        height: 66px;
        background-color: lightgreen;
        font-size: 22px;
        color: white;
        line-height: 66px;
        text-align: center;
      }
      button {
        border: 0;
        width: 77px;
        height: 40px;
        font-size: 18px;
        border-radius: 3px;
        font-weight: bold;
      }
      .start {
        position: absolute;
        top: 125px;
        left: 152px;
        color: red;
      }
      .end {
        position: absolute;
        top: 125px;
        left: 278px;
      }
    </style>
  </head>

  <body>
    <div class="box">
      <div class="box-name">请点击"开始按钮"</div>
      <button class="start">开始</button>
      <button class="end" disabled>停止</button>
    </div>
    <script>
      // 获取元素
      let box_name = document.querySelector('.box-name')
      let start = document.querySelector('.start')
      let end = document.querySelector('.end')

      // 生成随机数
      function getRandom(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min
      }

      // 初始化数据
      let arr = ['小红', '小明', '灵犀', '李四', '张三']
      let time = 0

      // 开始按钮监听事件
      start.addEventListener('click', () => {
        end.disabled = false
        start.disabled = true
        time = setInterval(() => {
          let num = getRandom(0, arr.length - 1)
          box_name.innerHTML = arr[num]
        }, 100)
      })

      // 停止按钮监听事件
      end.addEventListener('click', () => {
        start.disabled = false
        end.disabled = true
        clearInterval(time)
      })
    </script>
  </body>
</html>

2. 事件类型

(1)焦点事件:表单搜索实例

HTML 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JS 事件</title>
    <style>
      input {
        height: 30px;
        border: 1px solid #ccc;
        padding-left: 10px;
        outline: none;
      }
      ul {
        display: none;
        list-style: none;
        position: absolute;
        top: 17px;
        left: 0px;
        border: 1px solid orange;
        padding-top: 13px;
        width: 168px;
        padding-left: 13px;
      }
      .box {
        position: relative;
      }
      ul li {
        height: 35px;
      }
      .dis {
        border: 1px solid orange;
      }
    </style>
  </head>

  <body>
    <div class="box">
      <input type="text" placeholder="小米手机" />
      <ul>
        <li>全部商品</li>
        <li>小米14</li>
        <li>小米手机</li>
        <li>小米12</li>
        <li>小米笔记本</li>
      </ul>
    </div>

    <script>
      let input = document.querySelector('input')
      let ul = document.querySelector('ul')

      input.addEventListener('focus', () => {
        input.className = 'dis'
        ul.style.display = 'block'
      })

      input.addEventListener('blur', () => {
        input.classList.remove('dis')
        ul.style.display = 'none'
      })
    </script>
  </body>
</html>

(2)鼠标事件:将上例的焦点事件改成鼠标移入、移出事件,效果相同:

(3)文本事件:记录用户输入的字数

HTML 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JS 事件</title>
    <style>
      #txt {
        width: 500px;
        height: 80px;
        border-radius: 10px;
        padding-left: 17px;
        padding-top: 13px;
        font-size: 20px;
      }
      div {
        position: relative;
        width: 500px;
      }
      p {
        position: absolute;
        top: -12px;
        right: 80px;
      }
      span {
        color: red;
      }
      button {
        position: absolute;
        top: 9px;
        right: -5px;
        width: 71px;
        height: 36px;
        background-color: lightblue;
        border: 0;
        color: #fff;
        font-size: 18px;
        border-radius: 4px;
      }
    </style>
  </head>

  <body>
    <textarea id="txt" cols="30" rows="10" maxlength="100" placeholder="输入文字..."></textarea>
    <div>
      <p><span>0</span> /200</p>
      <button>发布</button>
    </div>

    <script>
      let txt = document.querySelector('#txt')
      let span = document.querySelector('span')

      txt.addEventListener('input', () => {
        // console.log(txt.value) // 用户输入的值
        // console.log(txt.value.length) // 用户输入的长度
        span.innerHTML = txt.value.length
      })
    </script>
  </body>
</html>

(4)鼠标点击事件

需求:用户点击全选,则下面的复选框全部选中;取消全选则全部取消,且文字对应变化

HTML 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JS 事件</title>
    <style>
      table,
      tr,
      td,
      th {
        border: 1px solid #ccc;
        text-align: center;
        border-collapse: collapse;
      }
      th {
        color: #fff;
        background-color: rgb(115, 210, 244);
      }
      th,
      td {
        width: 120px;
        height: 40px;
        font-size: 18px;
      }
      input {
        border: 1px solid #ccc;
      }
    </style>
  </head>

  <body>
    <table>
      <tr>
        <th><input type="checkbox" class="all" /><span>全选</span></th>
        <th>商品</th>
        <th>商家</th>
        <th>价格</th>
      </tr>
      <tr>
        <td><input type="checkbox" class="ck" /></td>
        <td>华为手机</td>
        <td>华为</td>
        <td>¥1999</td>
      </tr>
      <tr>
        <td><input type="checkbox" class="ck" /></td>
        <td>小米手机</td>
        <td>小米</td>
        <td>¥4999</td>
      </tr>
      <tr>
        <td><input type="checkbox" class="ck" /></td>
        <td>苹果手机</td>
        <td>苹果</td>
        <td>¥9999</td>
      </tr>
    </table>

    <script>
      let all = document.querySelector('.all')
      let span = document.querySelector('span')
      let ck = document.querySelectorAll('.ck')

      all.addEventListener('click', () => {
        console.log(all.checked)
        for (let i = 0; i < ck.length; i++) {
          ck[i].checked = all.checked
        }
        span.innerHTML = all.checked ? '取消' : '全选'
      })
    </script>
  </body>
</html>

(5)同时给多个元素绑定相同事件

HTML 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JS 事件</title>
    <style>
      table,
      tr,
      td,
      th {
        border: 1px solid #ccc;
        text-align: center;
        border-collapse: collapse;
      }
      th {
        color: #fff;
        background-color: rgb(115, 210, 244);
      }
      th,
      td {
        width: 120px;
        height: 40px;
        font-size: 18px;
      }
      input {
        border: 1px solid #ccc;
      }
    </style>
  </head>

  <body>
    <table>
      <tr>
        <th><input type="checkbox" class="all" /><span>全选</span></th>
        <th>商品</th>
        <th>商家</th>
        <th>价格</th>
      </tr>
      <tr>
        <td><input type="checkbox" class="ck" /></td>
        <td>华为手机</td>
        <td>华为</td>
        <td>¥1999</td>
      </tr>
      <tr>
        <td><input type="checkbox" class="ck" /></td>
        <td>小米手机</td>
        <td>小米</td>
        <td>¥4999</td>
      </tr>
      <tr>
        <td><input type="checkbox" class="ck" /></td>
        <td>苹果手机</td>
        <td>苹果</td>
        <td>¥9999</td>
      </tr>
    </table>

    <script>
      let all = document.querySelector('.all')
      let span = document.querySelector('span')
      let ck = document.querySelectorAll('.ck')

      all.addEventListener('click', () => {
        console.log(all.checked)
        for (let i = 0; i < ck.length; i++) {
          ck[i].checked = all.checked
        }
        span.innerHTML = all.checked ? '取消' : '全选'
      })

      for (let i = 0; i < ck.length; i++) {
        // 为元素绑定相同事件
        ck[i].addEventListener('click', () => {
          // console.log(ck[i].checked)
          // 点击任何一个小按钮,都要遍历所有的,查看是否有没被选中的
          for (let j = 0; j < ck.length; j++) {
            // 如果有没被选中的,就退出循环
            if (!ck[j].checked) {
              span.innerHTML = '全选'
              all.checked = false
              return
            }
          }

          // 循环结束说明都被选中了
          span.innerHTML = '取消'
          all.checked = true
        })
      }
    </script>
  </body>
</html> 

(6)购物车加减操作

需求:用户点击加号,文本框数值加1;点击减号,则减1,如果文本框的值为1,则减号禁用

HTML 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JS 事件</title>
    <style>
      * {
        box-sizing: border-box;
      }
      input {
        position: relative;
        width: 130px;
        height: 58px;
        border: 1px solid #ccc;
        outline: none;
        line-height: 58px;
        padding-left: 48px;
      }
      .add {
        position: absolute;
        top: 8px;
        left: 108px;
        width: 30px;
        height: 30px;
        background-color: #cad4d7;
        line-height: 30px;
        text-align: center;
        border: 1px solid #ccc;
      }
      .sub {
        position: absolute;
        top: 36px;
        left: 108px;
        width: 30px;
        height: 30px;
        background-color: #cad4d7;
        line-height: 30px;
        text-align: center;
        border: 1px solid #ccc;
      }
    </style>
  </head>

  <body>
    <input type="text" value="1" />
    <button class="add">+</button>
    <button class="sub" disabled>-</button>

    <script>
      let txt = document.querySelector('input')
      let add = document.querySelector('.add')
      let sub = document.querySelector('.sub')

      add.addEventListener('click', () => {
        txt.innerHTML = txt.value++
        sub.disabled =  false
      })

      sub.addEventListener('click', () => {
        txt.innerHTML = txt.value--
        sub.disabled = txt.value <= 1 ? true : false
      })
    </script>
  </body>
</html>

分析:

  • 获取表单元素、按钮元素;
  • 给按钮注册点击事件,获取表单的值;
  • 每点一次加号按钮,表单的数值就加1;
  • 每点一次减号按钮,则表单的数值减1,自减结束后,需要判断表单的值是否小于等于1,如果表单的值小于等于1,则减号按钮禁用
相关推荐
恋猫de小郭25 分钟前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端