WebAPI(二)、DOM事件监听、事件对象event、事件流、事件委托、页面加载与滚动事件、页面尺寸事件

news2025/4/20 5:41:26

文章目录

  • 一、 DOM事件
    • 1. 事件监听
    • 2. 事件类型
      • (1)、鼠标事件
      • (2)、焦点事件
      • (3)、键盘事件
      • (4)、文本事件
    • 3. 事件对象
      • (1)、获取事件对象
      • (2)、事件对象常用属性
    • 4. 环境对象 this
    • 5. 回调函数
  • 二、 DOM事件进阶
    • 1. 事件流
      • (1)、 捕获阶段
      • (2)、 冒泡阶段
      • (3)、 阻止冒泡
      • (4) 、阻止元素默认行为
      • (5) 、解绑事件
    • 2. 事件委托
    • 3. 其他事件
      • (1)、页面加载事件load
      • (2)、页面滚动事件scroll
      • (3)、页面滚动事件获取位置(scrollTop)
      • (4)、页面滚动到指定坐标scrollTo
    • 4. 页面尺寸事件
      • (1)、获取元素宽高(client)
      • (2)、窗口尺寸发生变化时触发的事件resize
    • 5. 页面尺寸与位置offset

一、 DOM事件

事件就是系统内发生的事件,比如单击一个按钮;
事件监听就是让程序检测是否有事件发生,并作出响应。

1. 事件监听

语法:元素对象.addEventListener(‘事件类型’,要执行的函数)

事件监听三要素

  • 事件源:哪个dom元素的事件被触发了
  • 事件类型:事件触发方式 click mouseover
  • 事件调用的函数:作出什么响应

事件监听版本

(1)、DOM L0: 事件源.on事件 = function(){} (比如btn.onclick = …)
(2)、 DOM L2: 事件源.addEventListener(‘事件类型’,要执行的函数)
区别: on方式会被覆盖,addEventListener可以绑定多次,拥有更多特性

案例:随机点名

在这里插入图片描述

需求:点击开始,随机抽取数组中的数并显示出来。点击结束,停止滚动,删除当前抽取的数据。抽到最后一个数据时,两个按钮禁用。

<body>
  <div class="box">
    <h1>随机点名</h1>
    <p>
      名字是:<span class="name">这里显示姓名</span>
    </p>
    <div class="operator">
      <button class="start">开始</button>
      <button class="end">结束</button>
    </div>
  </div>
  <script>
    // 1. 数组,为了方便观察,用数字代替姓名
    const nameList = [1,2,3,4]
    // 获取元素
    const name = document.querySelector('.box .name')
    const start = document.querySelector('.start')
    const end = document.querySelector('.end')
    let timeId = 0
    let num = 0
    // 3. 事件监听
    start.addEventListener('click', function () {
    // 如果数组中只有一个值,两个按钮禁用
       if (nameList.length === 1) {
        start.disabled = true
        end.disabled = true
      }
      timeId = setInterval(function () {
        // 滚动姓名
        num = Math.floor(Math.random() * nameList.length)
        name.innerHTML = nameList[num]
      }, 100)
    })
    // 4. 关闭事件
    end.addEventListener('click', function () {
      clearInterval(timeId)
      // 删除当前抽取的数组
      nameList.splice(num, 1)
    })
  </script>
</body>

2. 事件类型

(1)、鼠标事件

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

(2)、焦点事件

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

(3)、键盘事件

  • 键盘按下 keydown
  • 键盘抬起触发 keyup

(4)、文本事件

  • 用户输入事件 input

案例:评论字数统计
思路:①监听用户输入 ②不断获取文本框内的字符长度,文本域.value.length ③ 把获得的数字给下面文本框
在这里插入图片描述

<body>
  <div class="comment">
    <div class="box">
      <textarea class="ipt"></textarea>
      <p><span class="left-num">200</span>/200字</p>
    </div>
    <button>发布</button>
  </div>
  <script>
    // 评论字数统计--- value.length
    const comment = document.querySelector('.comment textarea')
    comment.addEventListener('input', function () {
      const left = 200 - comment.value.length
      document.querySelector('.box .left-num').innerHTML = left
    })
  </script>
</body>

3. 事件对象

事件对象也是个对象,包含事件触发的相关信息

(1)、获取事件对象

在事件监听的回调函数中第一个参数就是事件对象,一般命名为event或e

元素.addEventListner('click',function(e){
    // e就是事件对象
})

(2)、事件对象常用属性

type:获取当前的事件类型
clientX/clientY:获取光标相对于浏览器可视窗口左上角的位置(可应用于商品的放大镜场景中,通过获取鼠标的位置来确定要放大的位置)
offsetX/offsetY:获取光标相对于当前DOM元素左上角的位置
key:用户按下的键盘键的值。现在不提倡使用keyCode

    const input = document.querySelector('input')
    input.addEventListener('keyup', function (e) {
      if (e.key === 'Enter') {
        console.log('我按下了回车键');
      }
    })

4. 环境对象 this

环境对象就是函数内部的this,代表当前函数运行时所处的环境
this指向函数的调用者。谁调用函数,this就是谁

  function fn () {
    console.log(this); // window
  }
  // 本质上是window调用的fn
  fn()  // 等价于 window.fn()

  // button
  const btn = document.querySelector('button');
  btn.addEventListener('click', function () {
    console.log(this); //this指的是btn对象
    this.style.color = 'red'
  })

5. 回调函数

就是把函数A当作参数传递给另一个函数B时,函数A叫做回调函数。
使用匿名函数作为回调函数比较常见.

  // 函数A作为参数传递给函数B时,函数A为回调函数
  // 使用场景1
  function fn () {
    console.log('我是回调函数');
  }
  setInterval(fn, 1000)

  // 使用场景2
  btn.addEventListener('click', function () {
    console.log('我也是回调函数');
  })

二、 DOM事件进阶

1. 事件流

事件流就是事件执行的整个流动路径;假设页面中有个button,当触发事件时,会经历两个阶段:
(1) 捕获阶段:从父到子(button)
(2) 冒泡阶段:从子(button)到父
在这里插入图片描述

(1)、 捕获阶段

从DOM根元素开始执行对应的事件
语法:DOM元素.addEventListener(事件类型,事件处理函数,是否使用捕获机制)

  • 第三个参数传入true代表是捕获阶段触发事件,传入false代表冒泡阶段触发事件
  • 若是L0监听事件(onclick),则只有冒泡阶段,没有捕获
<body>
  <div class="father">
    <div class="son"></div>
  </div>
  <script>
    //点击son标签,依次弹出:grandpa,father,son
    
    // document.addEventListener 给最大的对象document添加监听事件
    document.addEventListener('click', function () {
      alert('grandpa')
    }, true)
    
    // father标签监听事件
    document.querySelector('.father').addEventListener('click', function () {
      alert('father')
    }, true)
    
    // son标签监听事件
    document.querySelector('.son').addEventListener('click', function () {
      alert('son')
    }, true)
</script>

页面中的body也有经历了捕获,但是没写对应代码所以没看到效果。事件捕获需要写对应代码才能看到效果

(2)、 冒泡阶段

冒泡:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件;

同名事件:做一次点击,则冒泡会执行每个父级的点击事件(而不是鼠标经过等其他事件),只不过就看该父级有没有添加事件监听。若未添加则看不到任何效果。

事件的触发默认是在冒泡阶段。

// 点击son,依次弹出son,father,grandpa
document.addEventListener('click', function () {
    alert('grandpa')
})
document.querySelector('.father').addEventListener('click', function () {
    alert('father')
})
document.querySelector('.son').addEventListener('click', function () {
    alert('son')
})

(3)、 阻止冒泡

因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素。若想把事件就限制在当前元素内,就需要阻止事件冒泡。
语法事件对象e.stopPropagation()

//阻止冒泡,需要用到事件对象--
document.addEventListener('click', function () {
    alert('biggest')
})
document.querySelector('.big').addEventListener('click', function () {
    alert('big')
})
document.querySelector('.small').addEventListener('click', function (e) {
    alert('small')
    e.stopPropagation()
})

注意:此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效

(4) 、阻止元素默认行为

阻止默认行为的发生,比如阻止链接跳转,表单域跳转;
语法:事件对象e.preventDefault()

 <!-- 点击链接不跳转 -->
<a href="https://www.baidu.com">百度</a>
<script>  
    const a = document.querySelector('a')
    a.addEventListener('click', function (e) {
      e.preventDefault()
    })
</script>

(5) 、解绑事件

const box = document.querySelector('.box')
// 传统L0注册
btn.onclick = function () {
    alert('点击')
}
// 解绑事件
btn.onclick = null

// 事件监听注册 L2
function fn () {
    console.log('点击事件');
}
box.addEventListener('click', fn)
// 解绑
box.removeEventListener('click', fn)

如果回调函数是匿名函数,则无法解绑

2. 事件委托

比如,快递小哥把一个班的快递委托给班主任,然后学生都找班主任领快递。这样就不用一个一个的找同学去送快递

事件委托是利用事件流的特征解决一些开发需求(只是一种技巧)

  • 优点:减少注册次数,可以提高程序性能
  • 原理:事件委托其实是利用事件冒泡的特点。给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件。

通过事件对象.target.tagName 可以获得真正触发事件的元素

  <!-- 需求:点击哪个li标签,哪个li变色 --> 
<ul>
    <li>one</li>
    <li>two</li>
    <li>three</li>
    <li>four</li>
    <li>five</li>
    <p>p标签</p>
  </ul>
  <script>
    // 点击哪个小li,哪个就变色
    const ul = document.querySelector('ul')
    ul.addEventListener('click', function (e) {
      console.dir(e.target);
       // 目标元素是li标签,如果是p标签,则颜色不变
      if (e.target.tagName === 'LI') {
        // 设置颜色!!!!!!
        e.target.style.color = 'red'
      }
    })
  </script>

3. 其他事件

之前写的JavaScript都放在HTML文件的底部,因为浏览器会按照代码在文件中的顺序加载HTML。若先加载的JavaScript想要修改下方的HTML,则会因为HTML尚未被加载而失效。

(1)、页面加载事件load

页面加载事件是加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件。

load:监听页面所有资源加载完毕

// 1.页面加载事件    
window.addEventListener('load', function () {
    // 执行的操作
    })
// 2.也可针对某个资源绑定load事件
img.addEventListener('load',function(){
    // 等图片加载完,再执行的操作
})

DOMContentLoaded事件:DOM元素加载完,无需等待样式表、图像等完全加载

document.addEventListener('DOMContentLoaded', function () {
 // 比load触发的快
})

应用场景:图片还没加载完,但是不影响页面进行交互

(2)、页面滚动事件scroll

滚动条在滚动的时候持续触发的事件;
应用场景:固定导航栏,返回顶部…

  • 监听整个页面滚动:给windowdocument添加scroll事件
// 页面滚动事件
window.addEventListener('scroll',function(){
    // 执行的操作
})
  • 监听某个元素的内部滚动,直接给某个元素加scroll即可

(3)、页面滚动事件获取位置(scrollTop)

scrollLeftscrollTop:获取元素内容往左、往上滚出去看不到的距离;
这两个值是可读写的,即可读值也可赋值。一般在scroll事件里获取被卷去的距离
在这里插入图片描述
案例一:获取div内容滚动的距离

<style>
    .box {
        overflow: scroll;
        width: 400px;
        height: 150px;
        border: 1px solid black;
        margin: 200px;
        display: block;
    }
</style>
<body>
    <div class="box">
        <p>滚动条在滚动的时候持续触发的事件</p>
        <p>滚动条在滚动的时候持续触发的事件</p>
        <p>滚动条在滚动的时候持续触发的事件</p>
        <p>滚动条在滚动的时候持续触发的事件</p>
        <p>滚动条在滚动的时候持续触发的事件</p>
        <p>滚动条在滚动的时候持续触发的事件</p>
        <p>滚动条在滚动的时候持续触发的事件</p>
        <p>滚动条在滚动的时候持续触发的事件</p>
        <p>滚动条在滚动的时候持续触发的事件</p>
        <p>滚动条在滚动的时候持续触发的事件</p>
        <p>滚动条在滚动的时候持续触发的事件</p>
        <p>滚动条在滚动的时候持续触发的事件</p>
        <p>滚动条在滚动的时候持续触发的事件</p>
        <p>滚动条在滚动的时候持续触发的事件</p>
    </div>

    <script>
        //div滚动获取
        const div = document.querySelector('div')
        div.addEventListener('scroll', function () {
            console.log(this.scrollTop);
        })
    </script>

在这里插入图片描述

案例二:获取页面滚动的距离

页面滚动的距离主要是看HTML滚动的距离;
获取HTML元素对象:document.documentElement

<style>
    body {
        height: 3000px;
    }
</style>
<body>
 <script>
        // 获取html:document.documentElement
        window.addEventListener('scroll', function () {
            // 这句话必须写在里面,因为要时刻获取最新的值
            const n = document.documentElement.scrollTop;
            console.log(n);
        })
 </script>

在这里插入图片描述

(4)、页面滚动到指定坐标scrollTo

语法:元素.scrollTo(x,y)
作用:把内容滚动到指定的坐标

4. 页面尺寸事件

(1)、获取元素宽高(client)

获取元素的可见部分宽高:clientWidthclientHeight (不包含边框、margin、滚动条等)。如果元素是个块级元素,clientWidth = width +padding;如果元素是个行内元素,clientWidth = 行内元素被内容撑开的宽度+padding

  <style>
    .box {
      width: 300px;
      height: 300px;
      padding: 10px;
      border: 10px solid black;
      background-color: skyblue;
    }
  </style>
<body>
  <div class="box">1212121222</div>
  <script>
    const box = document.querySelector('.box');
    console.log(box.clientWidth); // 320 width+padding,不包含border的宽度
  </script>
</body>

(2)、窗口尺寸发生变化时触发的事件resize

window.addEventListener('resize', function () {
    // 页面尺寸发生变化时,触发的事件
    // 检测html可视区宽度变化
    const n = document.documentElement.clientWidth
    console.log(n);
})

5. 页面尺寸与位置offset

通过JS的方式,得到元素在页面中的位置;这样当页面滚动到这个位置时,可进行一些操作,就不用自己计算了

  • 获取元素自身宽高:offsetWidth与offsetHeight
    • 获取出来的是数值,方便计算
    • offsetWidth与offsetHeight是自身的宽高+padding+border
    • 获取的是可视宽高,如果盒子是隐藏的,获取的结果是0
  • 获取位置:offsetLeftoffsetTop
    • 获取元素距离自己有定位父级元素的左、上距离;
    • offsetLeft与offsetTop是只读属性
<style>
        .box {
            width: 100px;
            height: 100px;
            background: skyblue;
            margin-left: 100px;
        }
        p {
            width: 50px;
            height: 50px;
            margin-left: 10px;
            background: pink;
        }
  </style>
</head>

<body>
    <div class="box">
        <p></p>
    </div>
    <script>
        const box = document.querySelector('.box')
        console.log(box.offsetLeft); // 108 = 100 + 8(body的8px外边距)
        const p = document.querySelector('p') 
        console.log(p.offsetLeft);
    </script>
</body>

若父级无定位,则向上找有定位的父级,值为距自己有定位的父级的距离
在这里插入图片描述
若给div加一个相对定位,position:relative,则p.offsetLeft = 10

页面滚动时,offset的值也不变

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2112579.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Optuna发布 4.0 重大更新:多目标TPESampler自动化超参数优化速度提升显著

Optuna这个备受欢迎的超参数优化框架在近期发布了其第四个主要版本。自2018年首次亮相以来&#xff0c;Optuna不断发展&#xff0c;现已成为机器学习领域的重要工具。其用户社区持续壮大&#xff0c;目前已达到以下里程碑&#xff1a; 10,000 GitHub星标每月300万 下载量16,00…

静心是良性循环

我发现一个挺有意思的事&#xff1a; 花时间修炼自己的心&#xff0c;让自己静心&#xff0c;就愿意多花时间修炼&#xff0c;会更加静心&#xff0c;这样就良性循环了。难的是刚开始&#xff0c;心不静&#xff0c;没时间修炼&#xff0c;心静不下来&#xff0c;更没时间修炼&…

分类中的语义一致性约束:助力模型优化

前言 这里介绍一篇笔者在去年ACL上发表的一篇文章&#xff0c;使用了空间语义约束来提高多模态分类的效果&#xff0c;类似的思路笔者也在视频描述等方向进行了尝试&#xff0c;也都取得了不错的效果。这种建模时对特征进行有意义的划分和约束对模型还是很有帮助的&#xff0c;…

基于人工智能的文本摘要生成系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 文本摘要生成是自然语言处理&#xff08;NLP&#xff09;中的一个重要任务&#xff0c;它旨在从长文本中提取出核心内容&#xff0c;生…

【学习笔记】SSL证书安全机制之证书验证

前言&#xff1a;每当Client从Server收到一张证书&#xff0c;有2件事Client需要去验证&#xff1a; 证书是否有效&#xff1f; 证书只是文件中的文本Client如何知道内容能够信任&#xff1f;Server是否是证书真正的拥有者&#xff1f; 证书可以公开获取Client如何知道Server是…

OM5光纤:优化您的数据中心性能

随着数据中心需求的持续增长&#xff0c;传统OM3和OM4光纤在传输距离和带宽方面的局限性日益显现。为应对这些挑战&#xff0c;OM5光纤应运而生。OM5光纤又称为宽带多模光纤&#xff08;WBMMF&#xff09;&#xff0c;通过支持单根光纤上的多波长传输&#xff0c;显著提高了数据…

ubuntu linux搭建lvgl v9

记录一下ubuntu linux搭建 lvgl的过程 本地环境:ubuntu 16.04 ubuntu lvgl sdl2 1 获取源码 git clone https://github.com/lvgl/lv_port_linux.git cd lv_port_linux/ git submodule update --init --recursive查看分支: git branch -a 我选择的是9.2(master分支一直在变动…

无人机执照拿到后怎么就业?方向有哪些?就业率如何?

无人机执照拿到后&#xff0c;就业方向广泛且多样&#xff0c;就业率也呈现出逐年上升的趋势。这主要得益于无人机技术的广泛应用和无人机市场的不断扩大。以下是对无人机执照持有者就业情况的详细分析&#xff1a; 就业方向 1. 无人机飞行操作&#xff1a; 无人机飞手可以从…

34465A-61/2 数字万用表(六位半)

34465A-61/2 数字万用表(六位半) 文章目录 34465A-61/2 数字万用表(六位半)前言一、测DC/AC电压二、测DC/AC电流四、测电阻五、测电容六、测二极管七、保存截图流程前言 1、6位半数字万用表通常具有200,000个计数器,可以显示最大为199999的数值。相比普通数字万用表,6位半…

经典文献阅读之--Representing 3D sparse map points....(用于相机重定位的3D点线稀疏地图)

0.简介 最近在视觉定位和地图制图方面取得了显著的进展&#xff0c;成功地将点特征和线特征进行了整合。然而&#xff0c;将定位框架扩展到包括额外的地图组件往往会导致对匹配任务的内存和计算资源需求增加。《Representing 3D sparse map points and lines for camera reloc…

尝试用java spring boot+VUE3实现前后端分离部署(8/31)

前言 这几天开学了&#xff0c;公司这边几个和学校对接的项目都挺忙的&#xff0c;然后我又开始有点闲的情况了。问大佬能不能继续看看若依的项目&#xff0c;大佬让我自己去学了。在看若依的项目的时候在想&#xff0c;python的FLASK后端实现和JAVA spring boot的实现差别大不…

通过指令微调提升语言模型性能

人工智能咨询培训老师叶梓 转载标明出处 如何让机器更好地理解和执行人类的指令一直是一个重要课题。Google的研究团队中提出了一种新的方法&#xff0c;通过指令微调&#xff08;instruction finetuning&#xff09;来提升语言模型的性能和泛化能力。 他们主要研究了如何通过…

美食|基于SpringBoot+vue的美食网站(源码+数据库+文档)

美食网站 基于SSMvue的美食网站 一、前言 二、系统设计 三、系统功能设计 系统功能实现 后台模块实现 管理员模块实现 用户模块实现 餐厅模块实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&…

JavaScript拷贝的艺术:玩转深拷贝和浅拷贝

前言 在实际的项目开发中&#xff0c;我们时刻都在使用数据拷贝功能&#xff0c;赋值、深拷贝和浅拷贝是前端开发中常见的概念&#xff0c;用于复制简单数据类型&#xff08;字符串、数值、布尔值&#xff09;和引用类型&#xff08;对象、数组&#xff09;。它们的主要区别在…

第十六篇:走入计算机网络的传输层--传输层概述

1. 传输层的功能 ① 分割与重组数据 一次数据传输有大小限制&#xff0c;传输层需要做数据分割&#xff0c;所以在数据送达后必然也需要做数据重组。 ② 按端口号寻址 IP只能定位数据哪台主机&#xff0c;无法判断数据报文应该交给哪个应用&#xff0c;传输层给每个应用都设…

中小型局域网组网规划与实施

一、绪论 1.1 背景 本课题以中小型企业网络搭建为背景&#xff0c;实现网络规划与设计和模拟。该企业网有四个部门&#xff0c;人力部、研发部、市场部和财务部&#xff0c;不同部门分别划分VLAN&#xff0c;不同VLAN之间分配不同的IP地址段。内外网之间要互通。 1.2 发展趋势…

关于前端分辨率兼容和显示器缩放兼容的处理

如下图所示&#xff0c;我们的电脑屏幕可以进行缩放&#xff0c;和分辨率的切换。 我们在项目开发中&#xff0c;时常需要适配不同的分辨率。 一般来说&#xff0c;开发人员电脑分辨率显示正常的页面&#xff0c;只会在更小的分辨率尺寸中出现问题。 所以当测试人员给我们提分…

QT项目实战之音乐播放器2.0版本

该版本相较于1.0版本最主要的不同在于连接数据库实现类似于歌曲收藏和取消收藏的功能。 详细情况看我的这篇文章http://t.csdnimg.cn/WS5s8。 效果展示 VSMyMusicShow2.0 define.h UseMySQL.h musicInfo.h VSMyMusicPlayer.h

出现 /www/server/mysql/bin/mysqld: Shutdown complete 的解决方法

目录 1. 基本知识1.1 查找my.cnf目录1.2 配置错误日志2. 问题所示3. 原理分析4. 解决方法1. 基本知识 主要补充一些基本知识的拓展 1.1 查找my.cnf目录 查看mysql默认读取my.cnf的目录: mysql --help|grep my.cnf 截图如下:(为了方便查看具体使用的配置文件在哪个路径)…

2024/9/6黑马头条跟学笔记(三)

D3 内容介绍 jdk8新特性&#xff0c;stream流&#xff0c;lambda表达式 ​ 自媒体前后端搭建 步骤 sql—— 实体—— 微服务拷贝&#xff0c;配置nacos—— spring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://192.168.233.136:3306/leadnews_…