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,则减号按钮禁用
相关推荐
喵叔哟28 分钟前
重构代码之取消临时字段
java·前端·重构
还是大剑师兰特1 小时前
D3的竞品有哪些,D3的优势,D3和echarts的对比
前端·javascript·echarts
王解1 小时前
【深度解析】CSS工程化全攻略(1)
前端·css
一只小白菜~1 小时前
web浏览器环境下使用window.open()打开PDF文件不是预览,而是下载文件?
前端·javascript·pdf·windowopen预览pdf
方才coding1 小时前
1小时构建Vue3知识体系之vue的生命周期函数
前端·javascript·vue.js
阿征学IT1 小时前
vue过滤器初步使用
前端·javascript·vue.js
王哲晓1 小时前
第四十五章 Vue之Vuex模块化创建(module)
前端·javascript·vue.js
丶21361 小时前
【WEB】深入理解 CORS(跨域资源共享):原理、配置与常见问题
前端·架构·web
发现你走远了1 小时前
『VUE』25. 组件事件与v-model(详细图文注释)
前端·javascript·vue.js
Mr.咕咕1 小时前
Django 搭建数据管理web——商品管理
前端·python·django