当前位置: 首页 > news >正文

【JavaScript】十五、事件对象与环境对象

文章目录

  • 1、事件对象
    • 1.1 获取事件对象
    • 1.2 常用属性
    • 1.3 案例:回车发布评论
  • 2、环境对象this
  • 3、回调函数
  • 4、案例:tab切换
  • 5、案例:全选文本框📖

1、事件对象

事件对象:

  • 也是个对象,object,里面存储了事件触发时的相关信息
  • 比如鼠标点击事件中,可以获取鼠标点了哪个位置

使用场景:

  • 从事件对象中获取数据,作出相应的操作
  • 比如判断用户按下的键是回车的话,就发布评论

1.1 获取事件对象

  • 在事件绑定的回调函数的第一个参数就是事件对象
  • 一般命名为event、ev、e

在这里插入图片描述

1.2 常用属性

  • type:获取当前的事件类型

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

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

  • key:用户按下的键盘键的值,现在不提倡使用keyCode

在这里插入图片描述

1.3 案例:回车发布评论

实现思路:

  • 用键盘事件 keydown 或者 keyup ,但多用keyup,用keydown的话,按下不松手会一直多次触发事件

  • 如果用户按下的是回车键盘,则发布信息

  • 发布信息,这里没有后端接口create + list接口,用数据渲染到对应标签内部模拟

<!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>评论回车发布</title>
  <style>
    .wrapper {
      min-width: 400px;
      max-width: 800px;
      display: flex;
      justify-content: flex-end;
    }

    .avatar {
      width: 48px;
      height: 48px;
      border-radius: 50%;
      overflow: hidden;
      background: url(./images/avatar.jpg) no-repeat center / cover;
      margin-right: 20px;
    }

    .wrapper textarea {
      outline: none;
      border-color: transparent;
      resize: none;
      background: #f5f5f5;
      border-radius: 4px;
      flex: 1;
      padding: 10px;
      transition: all 0.5s;
      height: 30px;
    }

    .wrapper textarea:focus {
      border-color: #e4e4e4;
      background: #fff;
      height: 50px;
    }

    .wrapper button {
      background: #00aeec;
      color: #fff;
      border: none;
      border-radius: 4px;
      margin-left: 10px;
      width: 70px;
      cursor: pointer;
    }

    .wrapper .total {
      margin-right: 80px;
      color: #999;
      margin-top: 5px;
      opacity: 0;
      transition: all 0.5s;
    }

    .list {
      min-width: 400px;
      max-width: 800px;
      display: flex;
    }

    .list .item {
      width: 100%;
      display: flex;
    }

    .list .item .info {
      flex: 1;
      border-bottom: 1px dashed #e4e4e4;
      padding-bottom: 10px;
    }

    .list .item p {
      margin: 0;
    }

    .list .item .name {
      color: #FB7299;
      font-size: 14px;
      font-weight: bold;
    }

    .list .item .text {
      color: #333;
      padding: 10px 0;
    }

    .list .item .time {
      color: #999;
      font-size: 12px;
    }
  </style>
</head>

<body>
  <div class="wrapper">
    <i class="avatar"></i>
    <textarea id="tx" placeholder="发一条友善的评论" rows="2" maxlength="200"></textarea>
    <button>发布</button>
  </div>
  <div class="wrapper">
    <span class="total">0/200</span>
  </div>
  <div class="list">
    <div class="item" style="display: none;">
      <i class="avatar"></i>
      <div class="info">
        <p class="name">清风徐来</p>
        <p class="text">大家都辛苦啦,感谢各位大大的努力,能圆满完成真是太好了[笑哭][支持]</p>
        <p class="time">2025-04-03 00:21:11</p>
      </div>
    </div>
  </div>

  <script>
    const tx = document.querySelector('#tx')
    const total = document.querySelector('.total')

    // 显示和隐藏文本字数统计结果
    tx.addEventListener('focus', function () {
      total.style.opacity = 1     // opacity,透明度样式,相比display,显示和隐藏更加柔和
    })
    tx.addEventListener('blur', function () {
      total.style.opacity = 0
    })

    // 文本事件,做字数统计并渲染
    tx.addEventListener('input', function () {
      // tx.value是获取到输入的字符串,后面.length获取字符串长度(包装类型)
      total.innerHTML = `${tx.value.length}/200字`
    })

    // 键盘事件
    const item = document.querySelector('.item')
    const text = document.querySelector('.text')  //评论内容
    tx.addEventListener('keyup', function (e) {
      // trim方法去除字符串左右两端端空格,中间的空格仍然保留不变
      if (e.key === "Enter") {
        if (tx.value.trim() !== '') {
          text.innerHTML = tx.value
          item.style.display = 'block'
        }
        // 清空刚才已发布的文字,不管你输入了是否为空,回车都清空文本框,并回复字符统计
        tx.value = ''
        total.innerHTML = '0/200字'
      }
    })
  </script>

</body>

</html>

效果:

在这里插入图片描述
在这里插入图片描述

2、环境对象this

  • 环境对象,即函数内部的特殊变量this
  • this代表这个函数运行时所处的环境
  • 函数调用方式不同,this指代的对象也不同,粗略判断为:谁调用这个函数,this就指代谁
<body>
    <button>按钮</button>
    <script>
        function fn() {
            console.log(this)
        }
        // 其实是window.fn()
        fn()

        // btn这个DOM对象在调用下面的function函数
        const btn = document.querySelector('button')
        btn.addEventListener('click', function () {
            console.log(this)
        })
    </script>
</body>

在这里插入图片描述
直接调用函数,其实相当于是 window.函数,所以 this 指代 window,而下面监听点击事件,则是button对象在调用,所以this就是这个DOM对象,因此,像实现点击按钮后按钮变色

在这里插入图片描述
以下两种写法等价:

在这里插入图片描述

3、回调函数

将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数

在这里插入图片描述
经常使用匿名函数做为回调函数

4、案例:tab切换

需求:鼠标经过不同的选项卡,底部可以显示 不同的内容

在这里插入图片描述

实现思路:获取所有的a标签,遍历绑定鼠标移入事件,数据的切换,通过样式控制显示和隐藏

<!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>tab栏切换</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    .tab {
      width: 590px;
      height: 340px;
      margin: 20px;
      border: 1px solid #e4e4e4;
    }

    .tab-nav {
      width: 100%;
      height: 60px;
      line-height: 60px;
      display: flex;
      justify-content: space-between;
    }

    .tab-nav h3 {
      font-size: 24px;
      font-weight: normal;
      margin-left: 20px;
    }

    .tab-nav ul {
      list-style: none;
      display: flex;
      justify-content: flex-end;
    }

    .tab-nav ul li {
      margin: 0 20px;
      font-size: 14px;
    }

    .tab-nav ul li a {
      text-decoration: none;
      border-bottom: 2px solid transparent;
      color: #333;
    }

    .tab-nav ul li a.active {
      border-color: #e1251b;
      color: #e1251b;
    }

    .tab-content {
      padding: 0 16px;
    }

    .tab-content .item {
      display: none;
    }

    .tab-content .item.active {
      display: block;
    }
  </style>
</head>

<body>
  <div class="tab">
    <div class="tab-nav">
      <h3>每日特价</h3>
      <ul>
        <li><a class="active" href="javascript:;">精选</a></li>
        <li><a href="javascript:;">美食</a></li>
        <li><a href="javascript:;">百货</a></li>
        <li><a href="javascript:;">个护</a></li>
        <li><a href="javascript:;">预告</a></li>
      </ul>
    </div>
    <div class="tab-content">
      <div class="item active"><img src="./images/tab00.png" alt="" /></div>
      <div class="item"><img src="./images/tab01.png" alt="" /></div>
      <div class="item"><img src="./images/tab02.png" alt="" /></div>
      <div class="item"><img src="./images/tab03.png" alt="" /></div>
      <div class="item"><img src="./images/tab04.png" alt="" /></div>
    </div>
  </div>

  <script>
    // 全选所有的a标签
    const as = document.querySelectorAll('.tab-nav a')
    // 遍历给每个a标签鼠标经过,变成高亮并切换对应的数据
    for (let i = 0; i < as.length; i++) {
      as[i].addEventListener('mouseenter', function () {
        // 移除有高亮样式的,排它
        document.querySelector('.tab-nav .active').classList.remove('active')
        // 谁在调用这个匿名函数?是as[i],所以as[i]就是这个匿名函数的this
        this.classList.add('active')

        // 修改数据
        document.querySelector('.tab-content .active').classList.remove('active')
        // 对应序号item对象的数据显示,数组序号从0开始,但item从1开始,所以+1
        document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')
      })
    }

  </script>

</body>

</html>

效果:

在这里插入图片描述

5、案例:全选文本框📖

需求1:大按钮控制所有小按钮,用户点击全选,则下面复选框全部选择,取消全选则全部取消
需求2:小按钮控制大按钮,下面某一项被取消选择了,则全选也要被取消

在这里插入图片描述

点击全选,下面每一项都选择,再点击全选,每一项都取消选择的实现思路是:

  • 点击全选的复选框,获取checked属性
  • 将下面所有小复选框的状态,统统更新成和全选复选框一致的

而第二个需求的实现,需要借助一个选择器:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        /* .ck是类选择器,对应我下面的class="ck",
        而.ck:checked则是css复选框选择器,选择被勾选的复选框 ,
        因此,下面这个代码可以实现:勾选后,复选框变大*/
        .ck:checked {
            width: 40px;
            height: 40px;
        }
    </style>
</head>

<body>

    <input type="checkbox" name="" id="" class="ck">
    <input type="checkbox" name="" id="" class="ck">
    <input type="checkbox" name="" id="" class="ck">
    <input type="checkbox" name="" id="" class="ck">

</body>

</html>

效果:勾选后,被.ck:checked选中,样式生效,变大

在这里插入图片描述
借助这个选择器,获取小复选框的个数,和已被checked的小复选框的个数,相等则表示全选,否则,更新全选框的checked为false

<!DOCTYPE html>

<html>

<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    table {
      border-collapse: collapse;
      border-spacing: 0;
      border: 1px solid #c0c0c0;
      width: 500px;
      margin: 100px auto;
      text-align: center;
    }

    th {
      background-color: #09c;
      font: bold 16px "微软雅黑";
      color: #fff;
      height: 24px;
    }

    td {
      border: 1px solid #d0d0d0;
      color: #404060;
      padding: 10px;
    }

    .allCheck {
      width: 80px;
    }
  </style>
</head>

<body>
  <table>
    <tr>
      <th class="allCheck">
        <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>
    <tr>
      <td>
        <input type="checkbox" name="check" class="ck">
      </td>
      <td>小米净水器</td>
      <td>小米</td>
      <td>4999</td>
    </tr>
    <tr>
      <td>
        <input type="checkbox" name="check" class="ck">
      </td>
      <td>小米电视</td>
      <td>小米</td>
      <td>5999</td>
    </tr>
  </table>
  <script>
    // 需求1:

    // 获取全选复选框的DOM对象
    const tableHead = document.querySelector('#checkAll')
    // 下面每一项的DOM对象
    const cks = document.querySelectorAll('.ck')
    tableHead.addEventListener('click', function (e) {
      console.log(this.checked) //表单元素属性checked,输出是true或者false
      // 遍历所有的小复选框☑️,让小复选框的checked = 表头复选框的checked
      for (let i = 0; i < cks.length; i++) {
        cks[i].checked = this.checked
      }
    })



    // 需求2:
    
    // 给所有的小复选框添加点击事件,里面比较checked的小复选框的总数,来更新大复选框的状态
    for (let i = 0; i < cks.length; i++) {
      cks[i].addEventListener('click', function () {
        // 获取所有已勾选的小复选框
        const checkedCks = document.querySelectorAll('.ck:checked')
        if (checkedCks.length === cks.length) {
          tableHead.checked = true
        } else {
          tableHead.checked = false
        }
        // 当然也可以三元
        // tableHead.checked = checkedCks.length === cks.length
      })
    }
  </script>
</body>

</html>

效果:

在这里插入图片描述

相关文章:

  • 跳跃游戏的最优解法——贪心算法的智慧与实践
  • 关于动态卷积
  • windows下GCC编译器使用FFTW预编译版共享库使用
  • 优秀的python可视化案例
  • Unity ViewportConstraint
  • 蓝桥杯 web 新鲜的蔬菜(css3)
  • javaweb自用笔记:Maven分模块设计与开发、Maven继承与聚合、Maven私服
  • 什么是数据
  • LogicFlow-前端流程图开发
  • 使用成员函数指针数组简化C++类中的操作
  • WebGL数学手记:矩阵基础
  • 安防监控/视频集中存储平台EasyCVR赋能养老院:构建多维度智能安防新生态
  • flink 增量快照同步文件引用关系和恢复分析
  • 中国金属通报杂志社中国金属通报编辑部2024年第12期目录
  • 一个开源的 VS Code 大模型聊天插件:Light-at
  • 搭建docker registry私服,并且支持https推送
  • 使用人工智能大模型腾讯元宝,如何快速编写活动记录?
  • ZKmall开源商城服务端验证:Jakarta Validation 详解
  • C++学习day7
  • Linux学习笔记(2) 命令基础:从概念到实践(期末,期中复习笔记全)
  • 移动端的网站/中国网络营销公司
  • 青岛哪家做网站的公司好/电商运营培训学费多少
  • 做哪类视频网站需要视频证书/磁力链接搜索引擎2021
  • 做网站编程要学什么/站长之家权重查询
  • 手机网站制作教程下载/网络营销促销方案
  • 网站分成几种类型/辅导机构