首页 > 其他分享 >【web APIs】快速上手Day03(Dom事件进阶)

【web APIs】快速上手Day03(Dom事件进阶)

时间:2024-07-04 17:26:21浏览次数:23  
标签:web const 进阶 Dom 事件 querySelector active document 页面

目录

Web APIs - 第3天

进一步学习 事件进阶,实现更多交互的网页特效,结合事件流的特征优化事件执行的效率

  • 掌握阻止事件冒泡的方法
  • 理解事件委托的实现原理

全选文本框案例

在这里插入图片描述

<!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. 获取大复选框
    const checkAll = document.querySelector('#checkAll')
    // 2. 获取所有的小复选框
    const cks = document.querySelectorAll('.ck')
    // 3. 点击大复选框  注册事件
    checkAll.addEventListener('click', function () {
      // 得到当前大复选框的选中状态
      // console.log(checkAll.checked)  // 得到 是 true 或者是 false
      // 4. 遍历所有的小复选框 让小复选框的checked  =  大复选框的 checked
      for (let i = 0; i < cks.length; i++) {
        cks[i].checked = this.checked
      }
    })
    // 5. 小复选框控制大复选框

    for (let i = 0; i < cks.length; i++) {
      // 5.1 给所有的小复选框添加点击事件
      cks[i].addEventListener('click', function () {
        // 判断选中的小复选框个数 是不是等于  总的小复选框个数
        // 一定要写到点击里面,因为每次要获得最新的个数
        // console.log(document.querySelectorAll('.ck:checked').length)
        // console.log(document.querySelectorAll('.ck:checked').length === cks.length)
        checkAll.checked = document.querySelectorAll('.ck:checked').length === cks.length
      })
    }
  </script>
</body>

</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>
    .father {
      width: 500px;
      height: 500px;
      background-color: pink;
    }

    .son {
      width: 200px;
      height: 200px;
      background-color: purple;
    }
  </style>
</head>

<body>
  <div class="father">
    <div class="son"></div>
  </div>
  <script>
    const fa = document.querySelector('.father')
    const son = document.querySelector('.son')
    // 山东  济南  蓝翔   目标(pink老师)  捕获阶段
    //  蓝翔  济南   山东   冒泡阶段
    document.addEventListener('click', function () {
      alert('我是爷爷')
    }, true)
    fa.addEventListener('click', function () {
      alert('我是爸爸')
    }, true)
    son.addEventListener('click', function () {
      alert('我是儿子')
    }, true)

  </script>
</body>

</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>
    .father {
      width: 500px;
      height: 500px;
      background-color: pink;
    }

    .son {
      width: 200px;
      height: 200px;
      background-color: purple;
    }
  </style>
</head>

<body>
  <div class="father">
    <div class="son"></div>
  </div>
  <script>
    const fa = document.querySelector('.father')
    const son = document.querySelector('.son')
    // 山东  济南  蓝翔   目标(pink老师)  捕获阶段
    //  蓝翔  济南   山东   冒泡阶段
    document.addEventListener('click', function () {
      alert('我是爷爷')
    })
    fa.addEventListener('click', function () {
      alert('我是爸爸')
    })
    son.addEventListener('click', function (e) {
      alert('我是儿子')
      // 组织流动传播  事件对象.stopPropagation()
      e.stopPropagation()
    })

  </script>
</body>

</html>

阻止冒泡

阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响到其对应的祖先元素。

在这里插入图片描述


在这里插入图片描述

总结:

1.阻止冒泡如何做?

事件对象.stopPropagation()

2.阻止元素默认行为如何做?

e.preventDefault()

解绑事件

on事件方式解绑

在这里插入图片描述

addEventListener方式解绑

在这里插入图片描述

注意事项-鼠标经过事件的区别

鼠标经过事件:

mouseover 和 mouseout 会有冒泡效果

mouseenter 和 mouseleave 没有冒泡效果 (推荐)

两种注册事件的区别

  • 传统on注册(L0)

    • 同一个对象,后面注册的事件会覆盖前面注册(同一个事件)
    • 直接使用null覆盖偶就可以实现事件的解绑
    • 都是冒泡阶段执行的
  • 事件监听注册(L2)

    • 语法: addEventListener(事件类型, 事件处理函数, 是否使用捕获)
    • 后面注册的事件不会覆盖前面注册的事件(同一个事件)
    • 可以通过第三个参数去确定是在冒泡或者捕获阶段执行
    • 必须使用removeEventListener(事件类型, 事件处理函数, 获取捕获或者冒泡阶段)
    • 匿名函数无法被解绑

事件委托

在这里插入图片描述

综合案例-tab栏切换改造

在这里插入图片描述

<!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:;" data-id="0">精选</a></li>
        <li><a href="javascript:;" data-id="1">美食</a></li>
        <li><a href="javascript:;" data-id="2">百货</a></li>
        <li><a href="javascript:;" data-id="3">个护</a></li>
        <li><a href="javascript:;" data-id="4">预告</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>
    // 采取事件委托的形式 tab栏切换
    // 1. 获取 ul 父元素 因为 ul只有一个
    const ul = document.querySelector('.tab-nav ul')
    // 获取 5个 item 
    const items = document.querySelectorAll('.tab-content .item')
    // 2. 添加事件
    ul.addEventListener('click', function (e) {
      // console.log(e.target)  // e.target是我们点击的对象
      // 我们只有点击了 a 才会 进行 添加类和删除类操作 
      // console.log(e.target.tagName)  // e.target.tagName 点击那个对象的 标签名
      if (e.target.tagName === 'A') {
        // console.log('我选的是a')
        // 排他思想 ,先移除原来的active  
        document.querySelector('.tab-nav .active').classList.remove('active')
        //当前元素添加 active  是 e.target
        // this 指向ul 不能用this 
        e.target.classList.add('active')

        // 下面大盒子模块
        // console.log(e.target.dataset.id)
        const i = +e.target.dataset.id
        // 排他思想 ,先移除原来的active 
        document.querySelector('.tab-content .active').classList.remove('active')
        // 对应的大盒子 添加 active 
        // document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')
        items[i].classList.add('active')
      }
    })
  </script>
</body>

</html>

其他事件

页面加载事件

在这里插入图片描述



在这里插入图片描述

总结:

  1. 页面加载事件有哪两个?如何添加?
  • load 事件

    • 监听整个页面资源给 window
  • DOMContentLoaded

    • document

    • 无需等待样式表、图像等完全加载

元素滚动事件

在这里插入图片描述

页面滚动事件-获取位置

在这里插入图片描述


在这里插入图片描述

页面滚动事件-滚动到指定的坐标

在这里插入图片描述

页面尺寸事件

在这里插入图片描述

页面尺寸事件-获取元素宽高

在这里插入图片描述

元素尺寸与位置

在这里插入图片描述



在这里插入图片描述

  1. offsetLeft和offsetTop 注意是只读属性

    • 获取元素距离自己定位父级元素的左、上距离
  2. element.getBoundingClientRect()

    • 方法返回元素的大小及其相对于视口的位置

注意:

  1. offsetWidth和offsetHeight是得到元素什么的宽高?

    • 内容 + padding + border
  2. offsetTop和offsetLeft 得到位置以谁为准?

    • 带有定位的父级

    • 如果都没有则以 文档左上角 为准

在这里插入图片描述

综合案例-实现bilibili 点击小滑块移动效果

在这里插入图片描述

  <script>
    // 1. 事件委托的方法 获取父元素 tabs-list
    const list = document.querySelector('.tabs-list')
    const line = document.querySelector('.line')
    // 2. 注册点击事件
    list.addEventListener('click', function (e) {
      // 只有点击了A 才有触发效果
      if (e.target.tagName === 'A') {
        // console.log(11)
        // 当前元素是谁 ?  e.target
        // 得到当前点击元素的位置
        // console.log(e.target.offsetLeft)
        // line.style.transform = 'translateX(100px)'
        // 把我们点击的a链接盒子的位置  然后移动
        line.style.transform = `translateX(${e.target.offsetLeft}px)`
      }
    })

  </script>

综合案例-电梯导航

在这里插入图片描述

需求:点击不同的模块,页面可以自动跳转不同的位置

模块分析:

①:页面滚动到对应位置,导航显示,否则隐藏模块

②:点击导航对应小模块,页面 会跳到对应大模块位置

③:页面滚动到对应位置,电梯导航对应模块自动发生变化

  <script>
    // 第一大模块,页面滑动可以显示和隐藏
    (function () {
      // 获取元素
      const entry = document.querySelector('.xtx_entry')
      const elevator = document.querySelector('.xtx-elevator')
      // 1. 当页面滚动大于 300像素,就显示 电梯导航
      // 2. 给页面添加滚动事件
      window.addEventListener('scroll', function () {
        // 被卷去的头部大于 300 
        const n = document.documentElement.scrollTop
        // if (n >= 300) {
        //   elevator.style.opacity = 1
        // } else {
        //   elevator.style.opacity = 0
        // }
        // 简写
        elevator.style.opacity = n >= entry.offsetTop ? 1 : 0
      })

      // 点击返回页面顶部
      const backTop = document.querySelector('#backTop')
      backTop.addEventListener('click', function () {
        // 可读写
        // document.documentElement.scrollTop = 0
        // window.scrollTo(x, y)
        window.scrollTo(0, 0)
      })
    })();

    // 第二第三都放到另外一个执行函数里面
    (function () {
      // 2. 点击页面可以滑动 
      const list = document.querySelector('.xtx-elevator-list')
      list.addEventListener('click', function (e) {
        // console.log(11)
        if (e.target.tagName === 'A' && e.target.dataset.name) {
          // 排他思想  
          // 先移除原来的类active 
          // 先获取这个active的对象
          const old = document.querySelector('.xtx-elevator-list .active')
          // console.log(old)
          // 判断 如果原来有active类的对象,就移除类,如果开始就没有对象,就不删除,所以不报错
          if (old) old.classList.remove('active')
          // 当前元素添加 active 
          e.target.classList.add('active')
          // 获得自定义属性  new   topic 
          // console.log(e.target.dataset.name)
          // 根据小盒子的自定义属性值 去选择 对应的大盒子
          // console.log(document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop)
          // 获得对应大盒子的 offsetTop
          const top = document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop
          // 让页面滚动到对应的位置
          document.documentElement.scrollTop = top

        }
      })


      // 3. 页面滚动,可以根据大盒子选 小盒子 添加 active 类
      window.addEventListener('scroll', function () {
        //  3.1  先移除类 
        // 先获取这个active的对象
        const old = document.querySelector('.xtx-elevator-list .active')
        // console.log(old)
        // 判断 如果原来有active类的对象,就移除类,如果开始就没有对象,就不删除,所以不报错
        if (old) old.classList.remove('active')
        // 3.2 判断页面当前滑动的位置,选择小盒子

        // 获取4个大盒子
        const news = document.querySelector('.xtx_goods_new')
        const popular = document.querySelector('.xtx_goods_popular')
        const brand = document.querySelector('.xtx_goods_brand')
        const topic = document.querySelector('.xtx_goods_topic')
        const n = document.documentElement.scrollTop
        if (n >= news.offsetTop && n < popular.offsetTop) {
          // 选择第一个小盒子
          document.querySelector('[data-name=new]').classList.add('active')
        } else if (n >= popular.offsetTop && n < brand.offsetTop) {
          document.querySelector('[data-name=popular]').classList.add('active')
        } else if (n >= brand.offsetTop && n < topic.offsetTop) {
          document.querySelector('[data-name=brand]').classList.add('active')
        } else if (n >= topic.offsetTop) {
          document.querySelector('[data-name=topic]').classList.add('active')
        }
      })

    })();

  </script>

标签:web,const,进阶,Dom,事件,querySelector,active,document,页面
From: https://blog.csdn.net/m0_49067926/article/details/140101837

相关文章

  • HTML5 WebSocket技术使用详解
    HTML5WebSocketAPI提供了一种在单个连接上进行全双工通信的方式。这意味着客户端和服务器可以同时发送和接收数据,而不需要像传统的HTTP请求那样进行多次请求和响应的轮询。WebSocket允许更实时的交互,非常适合需要快速、连续数据交换的应用场景,如在线游戏、实时通讯和股票行......
  • Python之Web框架Django
    官网https://www.djangoproject.com/download/安装djangopip安装django#查看python版本,版本显示如下Python3.12.1python3-V#安装djangopython3-mpipinstallDjango==5.0.6#查看django版本python3-mdjango--version通过Django包离线安装下载Django项目并......
  • 详解Web应用安全系列(7)使用具有已知漏洞的组件
    使用具有已知漏洞的组件,这种安全漏洞普遍存在,基于组件开发的模式使得多数开发团队根本不了解其应用或API中使用的组件,更谈不上及时更新这些组件了。下面就分别以.NET和Java各分享一个案例。.NET案例:XmlSerializer反序列化漏洞案例描述在.NET框架中,XmlSerializer类是一个常......
  • JavaWeb—JDBC篇
    概述jdbc是javaWeb的技术框架定义JDBC(JavaDatabaseConnectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,(java.sql,javax.sql)使用这些类库可以以一种标准的方法、方便地访问数据库资源。作用......
  • AI大模型实战进阶:内容审核应用深度解析
    1.背景介绍内容审核是指对互联网上的内容进行审核的过程,主要包括文本、图像、音频和视频等多种形式的内容。随着互联网的普及和用户生成内容的增加,内容审核的重要性也不断提高。人工审核不能满足需求,因此需要借助人工智能技术来自动化审核。AI大模型在内容审核领域具有广泛......
  • 分享:Motionity-开源的Web端动画编辑器
    Motionity是一个免费且开源的Web端动画编辑器,它结合了AfterEffects和Canva的优点,为用户提供了强大的动画编辑功能。支持视频剪切、图像搜索过滤、文本动画库、图层蒙版等功能。一、项目背景与特点开源项目:Motionity是一个开源项目,这意味着用户可以自由地查看、使用、修改和......
  • web前端基础(一)
    文本标签:快捷键:<!DOCTYPEhtml><html>  <head>    <metacharset="utf-8"    <title>hellohtml</title>  </head>  <body>    <!--    1.常用快捷键    ctrl+s保存    ctrl+x剪切  ......
  • idea Webstorm Pycharm2024最新版 永久使用教程 附激活码亲测可用2099年
    IDEA2024的激活与安装(全网最靠谱,最快捷的方式)大家都在为使用IDEA需要收费而烦恼。IDEA,idea即IntelliJIDEA,是一款强大的集成开发环境,广泛应用于Java开发。但是IDEA是付费的,免费版功能有太少,怎么才能既免费,又能使用上正式版呢!当然还是激活啦(不是正版用不起,而是‘激活’更有性价......
  • springboot项目国产化适配,jar改war包碰到的坑-tomcat版本要适配(非法访问:此Web应用程序
    项目原来是jar包运行,国产化适配要改成war包。可以参考https://blog.csdn.net/NAMELZX/article/details/138123405或者其他jar 改成 war 的文章。改成war后,在本地tomcat8上运行,一直报org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading非法......
  • springboot基于web的酒店客房管理系统
    文章目录目录文章目录论文目录项目介绍开发环境系统实现论文参考论文目录1系统概述1.1研究背景1.2研究目的1.3系统设计思想2相关技术2.1 MYSQL数据库2.2 B/S结构2.3 SpringBoot框架简介2.4 VUE框架简介3系统分析3.1可行性分析3.1.1技术......