【前端|Javascript第4篇】详解Javascript的事件模型:小白也能轻松搞懂!

news/2025/2/26 13:40:46

在这里插入图片描述
前言

在当今数字时代,前端技术正日益成为塑造用户体验的关键。而其中一个不可或缺的核心概念就是JavaScript的事件模型。或许你是刚踏入前端领域的小白,或者是希望深入了解事件模型的开发者,不论你的经验如何,本篇博客都将带你揭开事件模型的神秘面纱。


🚀 作者简介:程序员小豪,全栈工程师,热爱编程,曾就职于蔚来、腾讯,现就职于某互联网大厂,技术栈:Vue、React、Python、Java
🎈 本文收录于小豪的前端系列专栏,后续还会更新前端入门以及前端面试的一些相关文章,手把手带你从零学习前端到面试找工作,并如果有想进入前端领域工作的同学,这个前端专栏会对你有所帮助,欢迎关注起来呀
🌼 本人也会持续的去关注AIGC以及人工智能领域的一些动向并总结到博客中,大家感兴趣的可以关注一下我的人工智能专栏
🌊 云原生的入门学习系列,大家有兴趣的可以看一看

1.事件与事件流

javascript中的事件,可以理解就是在HTML文档或者浏览器中发生的一种交互操作,使得网页具备互动性, 常见的有加载事件、鼠标事件、自定义事件等

由于DOM是一个树结构,如果在父子节点绑定事件时候,当触发子节点的时候,就存在一个顺序问题,这就涉及到了事件流的概念

事件流都会经历三个阶段:

  • 事件捕获阶段(capture phase)
  • 处于目标阶段(target phase)
  • 事件冒泡阶段(bubbling phase)
    在这里插入图片描述
    事件冒泡是一种从下往上的传播方式,由最具体的元素(触发节点)然后逐渐向上传播到最不具体的那个节点,也就是DOM中最高层的父节点
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件冒泡</title>
    </head>
    <body>
        <button id="clickMe">按钮</button>
    </body>
</html>

然后,我们给button和它的父元素,加入点击事件

javascript">var button = document.getElementById('clickMe');

button.onclick = function() {
  console.log('1.Button');
};
document.body.onclick = function() {
  console.log('2.body');
};
document.onclick = function() {
  console.log('3.document');
};
window.onclick = function() {
  console.log('4.window');
};

最后得到的输出如下:
在这里插入图片描述
点击事件首先在button元素上发生,然后逐级向上传播

事件捕获与事件冒泡相反,事件最开始由不太具体的节点最早接受事件, 而最具体的节点(触发节点)最后接受事件

2. 事件模型

事件模型可以分为三种:

原始事件模型

原始事件模型(DOM0级事件模型)是事件绑定的最简单方式,适用于那些想要快速添加事件监听的场景。这种模型有两种绑定方式:直接在HTML代码中绑定和通过JS代码绑定。让我们来看看它们的特点和应用。

HTML中直接绑定事件

<input type="button" onclick="javascript language-javascript">fun()">

通过JS代码绑定事件

var btn = document.getElementById('btn');
btn.onclick = fun;

原始事件模型的特点:

  • 绑定速度快: 原始事件模型绑定速度非常快,但也可能因为绑定过于迅速,导致事件无法在页面完全加载时执行。
  • 仅支持冒泡: 原始事件模型只支持事件冒泡,不支持捕获。
  • 同类型事件只能绑定一次: 如果尝试为同一个元素绑定多个同类型事件,后绑定的事件会覆盖之前的事件。
<input type="button" id="btn" onclick="fun1()">

var btn = document.getElementById('btn');
btn.onclick = fun2;

对于上面的情况,尝试为同一个按钮绑定两个点击事件时,后绑定的事件会覆盖之前的事件。

要删除DOM0级事件处理程序,只需将对应的事件属性置为null即可。

btn.onclick = null;

标准事件模型

标准事件模型(DOM2级事件模型)是更加强大和灵活的事件处理方式。在标准事件模型中,一个事件共有三个阶段:捕获阶段、处理阶段和冒泡阶段。让我们深入了解标准事件模型的特点和使用方法。

事件捕获阶段、处理阶段和冒泡阶段

  • 事件捕获阶段: 事件从document向下传播到目标元素,检查经过的节点是否绑定了事件监听函数,如果有则执行。
  • 事件处理阶段: 事件到达目标元素,触发目标元素的监听函数。
  • 事件冒泡阶段: 事件从目标元素冒泡回document,依次检查经过的节点是否绑定了事件监听函数,如果有则执行。

在标准事件模型中,事件绑定和移除监听函数的方式如下:

addEventListener(eventType, handler, useCapture);
removeEventListener(eventType, handler, useCapture);

标准事件模型的特点:

  • 支持多个事件处理器: 在一个DOM元素上可以绑定多个事件处理器,它们不会相互冲突。
btn.addEventListener('click', showMessage1, false);
btn.addEventListener('click', showMessage2, false);
btn.addEventListener('click', showMessage3, false);
  • 执行时机: useCapture参数设置为true时,在捕获阶段执行监听函数;设置为false时,在冒泡阶段执行监听函数。

通过以下例子,我们可以更好地理解事件处理阶段的执行时机:

<div id='div'>
    <p id='p'>
        <span id='span'>点击我!</span>
    </p >
</div>

设置点击事件:

var div = document.getElementById('div');
var p = document.getElementById('p');

function onClickFn (event) {
    var tagName = event.currentTarget.tagName;
    var phase = event.eventPhase;
    console.log(tagName, phase);
}

div.addEventListener('click', onClickFn, false);
p.addEventListener('click', onClickFn, false);

点击"点击我!"后,输出如下:

P 3
DIV 3

我们可以看到,pdiv都在冒泡阶段响应了事件,由于冒泡的特性,内部的p先于外层的div作出了响应。

如果我们将useCapture参数改为true

div.addEventListener('click', onClickFn, true);
p.addEventListener('click', onClickFn, true);

输出如下:

DIV 1
P 1

两者在捕获阶段响应事件,因此div会先于p作出响应。

IE事件模型

IE事件模型共有两个过程:

  • 事件处理阶段:事件到达目标元素, 触发目标元素的监听函数。
  • 事件冒泡阶段:事件从目标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行

事件绑定监听函数的方式如下:

attachEvent(eventType, handler)

事件移除监听函数的方式如下:

detachEvent(eventType, handler)

举个例子:

var btn = document.getElementById('.btn');
btn.attachEvent(‘onclick’, showMessage);
btn.detachEvent(‘onclick’, showMessage);

总结

在本篇博客中,我们一起探索了JavaScript事件模型的四大概念:事件与事件流、原始事件模型、标准事件模型、IE事件模型。JavaScript是一门非常强大且广泛应用的编程语言。掌握了这些基本的语法和概念,你已经具备了入门JavaScript编程的基础。未来,你将能够创建更加交互性的网页,实现更多惊艳的动态效果,甚至搭建出属于自己的Web应用。但这只是一个开始,还有许多更深入的主题等待你去探索。
后续我们这个前端专栏还会讲述作用域、事件模型、内置对象、垃圾回收、js算法技巧、Vue入门实战、React实战、前端面试题等等文章,如果您感兴趣的话,欢迎点赞三连并关注我以及我的前端专栏,我们下期文章再见。


http://www.niftyadmin.cn/n/4937203.html

相关文章

【Docker】如何在设计 dockerfile 过程中,设置容器启动后的定时任务

如何在设计 dockerfile 过程中&#xff0c;设置容器启动后的定时任务 jwensh 2023.08.14 文章目录 如何在设计 dockerfile 过程中&#xff0c;设置容器启动后的定时任务1. 基于 alpine 设计 dockerfile 过程中&#xff0c;设置容器启动后的定时任务2. 基于 CentOS 设计 Dockerf…

探索Python中的函数和类:构建模块化和面向对象的程序

文章目录 &#x1f340;引言&#x1f340;函数&#xff1a;模块化编程的基石&#x1f340;类&#xff1a;面向对象编程的基石&#x1f340;函数和类的结合&#xff1a;构建高效的程序&#x1f340;简单的文字冒险游戏 &#x1f340;引言 Python作为一种多范式的编程语言&#x…

[Mongodb 5.0]聚合操作

本文对应Aggregation Operations — MongoDB Manual 正文 此章节主要介绍了Aggregation Pipeline&#xff0c;其实就是将若干个聚合操作放在管道中进行执行&#xff0c;每一个聚合操作的结果作为下一个聚合操作的输入&#xff0c;每个聚合指令被称为一个stage。 在正式开始学…

【多视重建】从Zero-123到One-2-3-45:多视角生成

文章目录 摘要一、引言二、相关工作三、Zero-1-to-33.1.学习如何控制照相机的视角3.2.视角作为条件的扩散3.3三维重构3.4 数据集 四、One-2-3-454.1 Zero123: 视角条件的 2D Diffusion4.2 NeRF优化&#xff1a;将多视图预测提升到三维图像4.3 基于不完美多视图的 神经表面重建*…

学习笔记整理-JS-05-数组

一、数组的定义和基本使用 1. 数组简介和定义 数组&#xff08;Array&#xff09;&#xff0c;顾名思义&#xff0c;用来存储一组相关的值&#xff0c;从而方便进行求和、计算平均数、逐项遍历等操作。 var scoreArr [96, 07, 76, 87, 100];数组是非常重要的一种数据结构。…

Chrome小技巧---多用户登录同一网站不串信息

测试中经常需要用到浏览器需要登录多个账号 但是有一个问题就是会串号 通过添加不同的用户再用这用户登录&#xff0c;就不串号了&#xff1a; 还可以在浏览器的偏好设置中添加启动地址 这样每次打开&#xff0c;就进到设置的地址中了

MISRA 2012学习笔记(2)-Rules 8.1-3

文章目录 Rules8.1标准的C环境Rule 1.1 程序不得违反标准 C 语法和约束&#xff0c;并且不得超出具体实现的编译限制Rule 1.2 不应该使用语言扩展Rule 1.3 不得发生未定义或严重的未指定行为 8.2未使用的代码(Unused code)Rule2.1 项目不应包含无法访问的代码Rule2.2 不得有无效…

DNS协议及其工作原理

DNS是域名系统&#xff08;Domain Name System&#xff09;的缩写&#xff0c;它是一种用于将域名转换为IP地址的分布式数据库系统。它是因特网的基石&#xff0c;能够使人们通过域名方便地访问互联网&#xff0c;而无需记住复杂的IP地址。 DNS的历史可以追溯到1983年&#xf…