Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >22 - 23 - 24 事件相关

22 - 23 - 24 事件相关

作者头像
前端黑板报
发布于 2022-12-01 08:57:46
发布于 2022-12-01 08:57:46
91700
代码可运行
举报
文章被收录于专栏:前端黑板报前端黑板报
运行总次数:0
代码可运行

事件和事件处理

原文地址:https://dev.to/bhagatparwinder/events-event-handling-f28

事件

你对动作(系统的或用户产生的)的响应就是调用一个事件,对事件的回应就是调用一个事件处理程序。

例如,当用户点击一个按钮后,我们可能会显示一个带信息的弹框,在这个例子中,事件是 click 处理结果就是展示一个弹框。

网页上会发生很多事件:

  1. 1. 用户 hover 一个元素上
  2. 2. 表单的提交
  3. 3. 视频停止播放
  4. 4. 用户从一个图片上滚动过去
  5. 5. 改变浏览器的大小
  6. 6. 按键
  7. 7. 文档加载结束

事件处理程序

我上面已经简单提到过,事件处理程序就是我们如何响应事件的方法。它是事件发生时执行的一块代码。

我们经常会把 event listenersevetn handlers 交替使用,同样你也可以像这样随意使用。

可是,它俩有点小区别,listeners 是监听一个事件的发生而 handler 是执行的具体代码。

案例

假设我们的页面有一个按钮。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<button class="btn-primary">Click Me!</button>

我们为按钮绑定了一个事件,当点击它时打印一条消息。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const myButton = document.querySelector(".btn-primary");

myButton.addEventListener("click", function() {
    console.log("The button was clicked");
});

发生了什么:

  1. 1. 我们使用 querySelector获取到浏览器 DOM 中的按钮;
  2. 2. 接着我们使用 addEventListener 添加了事件侦听器;
  3. 3. addEventListner 接受了两个参数(实际可以接受三个参数);
  4. 4. 第一个参数是事件类型,这个例子中的事件类型是 click;
  5. 5. 第二个参数就是一旦点击时执行的回调函数

浏览器知道用户什么时候点击了按钮,同时为有类名 btn-primary 的按钮注册了一个事件,然后执行相关的事件处理程序,将会打印:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
The button was clicked

回调方法是一个匿名函数,它不能被其它地方引用。我们不经常使用匿名函数,可以创建一个命名函数然后传递给它。命名函数是可重用性的首选,它使我们能够在以后删除事件侦听器。

使用命名函数

事件处理器可以是一个命名函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const myButton = document.querySelector(".btn-primary");

const handleClick = function() {
    console.log("The button was clicked");
};

myButton.addEventListener("click", handleClick);

这样并不仅仅是代码更简洁,它还有两个优点:

  1. 1. 重用性:设想你有很多按钮需要打印相同的语句,一个命名函数可以被使用多次而不要写重复的代码。
  2. 2. 移出事件侦听器:使用 removeEventListener 来移出事件处理程序,为了移出它需要传递两个关键参数。第一个是实际类型,第二个是事件处理程序。若事件处理程序是一个匿名函数我们无法指定第二个参数。在这个例子中是命名函数,我们可以这样做:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
myButton.removeEventListener("click", handleClick);

事件冒泡

原文地址:https://dev.to/bhagatparwinder/event-bubbling-pb3

简介

上面我们谈了事件和事件处理程序,以及为事件添加事件处理程序。当事件发生时事件处理程序将会被调用。

JavaScript 中的事件冒泡是指当元素上发生一个事件时,关联的事件处理程序会被调用,紧接着是父级元素和更上层元素的事件处理程序也会被调用。

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<div onclick="alert('Click Event Happened')">
    <p>If you have click this paragraph in the browser, the onclick handler of the div will get invoked.</p>
</div>

上面的例子是:点击 p 标签内的文本时,会触发 div 上的 onclick 事件。这就是 p 上发生的事件冒泡到了 div 上。

即使有 n 多层嵌套的元素上面的模式依旧也会发生。

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<span onclick="alert('Span Clicked')">
    <div onclick="alert('Div Clicked')">
        <p onclick="alert('Paragraph Clicked')">Click Me.</p>
    </div>
</span>

若我们点击了 p 标签,浏览器会触发三次弹框。

找到事件的源头元素

当事件冒泡经过多层时,很难追踪到是哪个元素产生了这一串的事件。可是 JavaScript 中很容易做到。

像上面的例子,若我们点击了 p 标签,targetevent.target 将会指向它,无论事件冒泡了多少层,而 event.target 永远不会改变,指向事件产生的源头。

如何阻止事件冒泡?

冒泡的事件将一直传递到 <html> 元素,有些还会到 document,其中一些进入window对象。

我们如果不想父级元素的事件发生,可以使用 event.stopPropagation()

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<div onclick="alert('This will not alert')">
  <button onclick="event.stopPropagation()">Click me</button>
</div>

若我们点击了带有 stopPropagation()的按钮,div 的事件处理程序或 alert 不会触发。

如何阻止同一个元素上的多个事件?

有时候我们会为同一个元素绑定同一个事件绑定多个事件处理程序,有时候期望阻止冒泡也想后面注册的同类型事件也被阻止,event.stopImmediatePropagation() 就可以做到。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  <div onclick="alert(1)">
    <div onclick="alert(2)">
      <div id="target">ppp</div>
    </div>
  </div>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let target = document.querySelector('#target')

function testClick1(event){
  alert(33)
}

function testClick2(event){
  alert(44)
  event.stopImmediatePropagation()
  //event.stopPropagation()
}


function testClick3(){
  alert(55)
}

function moveHandler(){
  alert('move')
}


target.addEventListener('click',testClick1)

target.addEventListener('click',testClick2)

target.addEventListener('click',testClick3)

上面会依次弹出:33,44,若把上面的注释换一下则依次弹出:33,44,55

在线案例:https://jsbin.com/xilorahomi/edit?html,js,output

参考文档:http://developer.mozilla.org/en-US/docs/Web/API/Event/stopImmediatePropagation

为何阻止事件冒泡可能会是错误的?

如果用户点击的元素事件处理程序带有stopPropagation() , document 上的点击事件处理程序(为了跟踪、分析或调用弹框)也不会被触发。所以谨慎的阻止事件冒泡。这个仅仅是一个例子,还有许多其它的副作用。

事件冒泡的例外情况

并不是所有的事件都会冒泡,任何与特定元素绑定事件不会冒泡,如下一些事件:

  • • load
  • • unload
  • • focus
  • • blur

事件捕获

原文地址:https://dev.to/bhagatparwinder/event-capturing-40o

事件捕获刚好和事件冒泡相反,事件冒泡中事件是从最内层元素逐渐向外扩散,而事件捕获则是从最外面元素向内直到目标元素。

事件捕获很少用到,开启事件捕获可以给 addEvenListener 传递第三个参数。

例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const myButton = document.querySelector(".btn-primary");

myButton.addEventListener("click", function() {
    console.log("The button was clicked");
}, { capture : true });

第三个参数设置为 true 来开启捕获,现在当一个事件发生时,它会从顶部一直向内流到目标元素,之后事件再冒泡。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<div id="p">
  <div id="m">
    <div id="c">Bubble and Capture</div>
  </div>
</div>

上面的结构只在最内层的事件开启捕获也是不行的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let p = document.querySelector('#p')
let m = document.querySelector('#m')
let c = document.querySelector('#c')

p.addEventListener('click',function(e){
  alert(e.eventPhase)
  alert('p')
})

m.addEventListener('click',function(e){
  alert(e.eventPhase)
  alert('m')
})

c.addEventListener('click',function(e){
  alert(e.eventPhase)
  alert('c')
},true)

结果一次弹出:2,c,3,m,3,p 其实还是冒泡的顺序,只有都加上或外面两层的事件加上才会有捕获的效果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let p = document.querySelector('#p')
let m = document.querySelector('#m')
let c = document.querySelector('#c')

p.addEventListener('click',function(e){
  alert(e.eventPhase)
  alert('p')
},true)

m.addEventListener('click',function(e){
  alert(e.eventPhase)
  alert('m')
},true)

c.addEventListener('click',function(e){
  alert(e.eventPhase)
  alert('c')
})

弹框结果:1,p,1,m,2,c,若只给中间的开启捕获呢?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let p = document.querySelector('#p')
let m = document.querySelector('#m')
let c = document.querySelector('#c')

p.addEventListener('click',function(e){
  alert(e.eventPhase)
  alert('p')
})

m.addEventListener('click',function(e){
  alert(e.eventPhase)
  alert('m')
},true)

c.addEventListener('click',function(e){
  alert(e.eventPhase)
  alert('c')
})

结果:1,m,2,c,3,p

16520216389621

实例:https://jsbin.com/wurabalaje/edit?html,js,output,在案例里来回切换一下true 再对照上图理解。

第三个参数并不一定要是一个对象,是一个 boolean 值 true 也行。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
myButton.addEventListener("click", function() {
    console.log("The button was clicked");
}, true);

总结,DOM 事件有三个阶段:

  1. 1. 捕获
  2. 2. 目标元素
  3. 3. 冒泡

通过 event.eventPhase 可以确定我们所处的阶段或在哪个事件处理程序中。

注意:若addEventListener中为了捕获使用了 true,那removeEventListener时也要使用相同的值。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端黑板报 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
事件
事件 JavaScript和HTML的交互是通过事件实现的。JavaScript采用异步事件驱动编程模型,当文档、浏览器、元素或与之相关对象发生特定事情时,浏览器会产生事件。如果JavaScript关注特定类型事件,那么它可以注册当这类事件发生时要调用的句柄。事件是某个行为或者触发,比如点击、鼠标移动..... 当用户点击鼠标时 当网页已加载时 当图像已加载时 当鼠标移动到元素上时 当用户触发按键时... 事件流 事件流描述的是从页面中接收事件的顺序,比如有两个嵌套的div,点击了内层的div,这时候是内层
小胖
2018/06/27
1.4K0
DOM事件基本概念大总结(前端必备)
事件流 这一概念源自于对事件触发对象的思考。例如常见的点击事件,鼠标移动事件。这些事件发生之时,往往不只是点击或者移动到某一特定元素上。 比如点击某一个按钮,而它是由上一层的父标签,或许在上一层还有父标签甚至是整个页面。因此点击一个元素可以看成是同时点击了父标签或者整个页面。那么此时事件应该怎么响应到指定标签呢? 事件冒泡 即事件从指定元素开始传播到最外层的元素,并且该事件不仅会在指定元素上发生,还会在传播过过程中的每一个元素上发生。 <html> <body> <div>
努力的Greatiga
2022/07/25
1.9K0
前端day16-JS(WebApi)学习笔记(事件补充、事件冒泡与捕获)
var code = e.keyCode || e.charCode || e.which;
帅的一麻皮
2020/05/05
1.8K0
js 事件笔记
在Web中, 事件在浏览器窗口中被触发,执行事先绑定的事件处理器(也就是事件触发时会运行的代码块),对事件做出响应。 用户在浏览器的任何一个操作都会去触发一个事件,JavaScript采用异步事件驱动编程模型,当文档、浏览器、元素或与之相关对象发生特定事情时,浏览器会产生事件。
bamboo
2019/01/29
11.2K0
js 事件笔记
JavaScript——DOM事件高级
此方法将指定的监听器注册到eventTarger(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。
岳泽以
2022/10/26
1.9K0
JavaScript——DOM事件高级
[javascript] 看知乎学习js事件触发过程
调用元素对象的addEventListener()方法,参数:事件,回调函数,是否捕获(true代表捕获阶段,false代表冒泡阶段,ie浏览器不支持在捕获阶段绑定事件因此一般写false)
唯一Chat
2019/09/10
3.8K0
[javascript] 看知乎学习js事件触发过程
事件
JavaScript与HTML之间的交互式通过事件实现的。 事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。可以使用侦听器(或处理程序)来预订事件,以便事件发生时执行相应的代码。
奋飛
2019/08/15
3.3K0
事件
利用 on 开头的事件,如 onclick, 同一个元素同一个事件只能设置一个处理函数,出现多个处理函数的话,后面的会覆盖前面的。
赤蓝紫
2023/01/01
1.4K0
事件
事件高级
给元素添加事件,称为注册事件或者绑定事件。 注册事件有两种方式:传统方式和方法监听注册方式
梨涡浅笑
2022/05/08
1.3K0
事件高级
JavaScript的事件
javascript与HTML之间的交互是通过事件实现的。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。
小小鱼儿小小林
2020/06/24
1.5K0
关于DOM事件流、DOM0级事件与DOM2级事件
DOM 事件模型包括捕获和冒泡,捕获是从上往下到达目标元素,冒泡是从当前元素,也就是目标元素往上到 window
Leophen
2019/08/26
2.2K0
JavaScript事件
JavaScript事件 对于事件来讲,首先,我们需要了解这样几个概念:事件;事件处理程序;事件类型;事件流;事件冒泡;事件捕获;事件对象;事件模拟,事件方面的性能优化(事件委托、移除事件处理程序); 事件的概念 事件:指的是文档或者浏览器窗口中发生的一些特定交互瞬间。我们可以通过监听器(或者处理程序)来预定事件,以便事件发生的时候执行相应的代码。 事件处理程序:我们用户在页面中进行的点击这个动作,鼠标移动的动作,网页页面加载完成的动作等,都可以称之为事件名称,即:click、mousemove、loa
汤高
2018/01/11
2.1K0
JavaScript事件
事件高级
eventTarget.addEventListener()方法将指定的监听器注册到 eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。
星辰_大海
2020/09/30
1.4K0
前端系列第2集-如何让事件先冒泡后获取?
事件冒泡是指当一个元素上的事件被触发后,该事件会从该元素开始向上冒泡,直到传播到文档对象,并且可以被其他元素捕获。默认情况下,事件是先捕获后冒泡。如果希望事件先冒泡后获取,可以使用以下两种方法之一:
达达前端
2023/10/08
2540
【Java 进阶篇】HTML DOM 事件详解
当用户在网页上点击按钮、输入文本、鼠标移动到某个区域或执行其他互动操作时,这些动作都可以触发事件。HTML DOM(文档对象模型)允许我们使用JavaScript来捕获、处理和响应这些事件,以实现网页的交互和动态性。本篇博客将围绕HTML DOM事件展开详细的解释,包括事件的类型、事件处理程序、事件对象和示例代码。让我们一起来深入了解吧。
繁依Fanyi
2023/10/22
3650
【Java 进阶篇】HTML DOM 事件详解
深入理解 DOM 事件机制
本文主要介绍 DOM 事件级别、DOM 事件模型、事件流、事件代理和 Event 对象常见的应用,希望对你们有些帮助和启发!
小生方勤
2019/06/02
2.9K1
JavaScript小技能:事件
JavaScript 在不同环境下使用不同的事件模型:不同的编程环境下的事件机制是不同的,比如JavaScript 网页上的事件机制不同于在其他环境中的事件机制。(Node.js 的事件模型、浏览器插件WebExtensions技术的事件模型)
公众号iOS逆向
2022/08/22
1.5K0
JavaScript小技能:事件
JavaScript事件探秘
事件流描述的是从页面中接收事件的顺序。IE的事件流是事件冒泡流,而Netscape的事件流是事件捕获流
张张
2019/12/26
9120
JavaScript基础-事件监听与处理
在Web开发中,事件驱动编程是核心机制之一,它使得页面能够响应用户的操作,如点击、滚动、键盘输入等。JavaScript提供了强大的事件监听与处理机制,让开发者能够轻松地为DOM元素绑定事件处理程序。本文将深入浅出地介绍JavaScript事件模型、绑定与解除事件监听器的方法,以及在实际应用中常见的问题与易错点,并通过代码示例给出避免策略。
Jimaks
2024/06/12
3220
js事件流机制
在JavaScript中事件流是指一个事件沿特定数据结构传播的一个过程。整个事件流总共包含三个阶段(从dome2来说):1.事件捕获阶段、2.处于事件目标阶段、3.事件冒泡阶段。下面我们来看一个图,只要是谈到事件流都会看到的一个图:
OECOM
2020/07/01
1.6K0
相关推荐
事件
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验