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


前言

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


🚀 作者简介:程序员小豪,全栈工程师,热爱编程,曾就职于蔚来、腾讯 ,现就职于某互联网大厂,技术栈:Vue、React、Python、Java

🎈 本文收录于小豪的前端系列专栏,后续还会更新前端入门以及前端面试 的一些相关文章,手把手带你从零学习前端到面试找工作,并如果有想进入前端领域工作的同学,这个前端专栏会对你有所帮助,欢迎关注起来呀

🌼 本人也会持续的去关注AIGC以及人工智能领域的一些动向并总结到博客中,大家感兴趣的可以关注一下我的人工智能专栏

🌊 云原生的入门学习系列,大家有兴趣的可以看一看

1.事件与事件流

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

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

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

  • 事件捕获阶段(capture phase)
  • 处于目标阶段(target phase)
  • 事件冒泡阶段(bubbling phase)

    事件冒泡是一种从下往上的传播方式,由最具体的元素(触发节点)然后逐渐向上传播到最不具体的那个节点,也就是DOM中最高层的父节点
html 复制代码
<!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级)
  • 标准事件模型(DOM2级)
  • IE事件模型(基本不用)

原始事件模型

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

HTML中直接绑定事件

html 复制代码
<input type="button" onclick="fun()">

通过JS代码绑定事件

js 复制代码
var btn = document.getElementById('btn');
btn.onclick = fun;

原始事件模型的特点:

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

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

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

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

js 复制代码
btn.onclick = null;

标准事件模型

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

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

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

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

js 复制代码
addEventListener(eventType, handler, useCapture);
removeEventListener(eventType, handler, useCapture);

标准事件模型的特点:

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

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

html 复制代码
<div id='div'>
    <p id='p'>
        <span id='span'>点击我!</span>
    </p >
</div>

设置点击事件:

js 复制代码
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);

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

js 复制代码
P 3
DIV 3

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

如果我们将useCapture参数改为true

js 复制代码
div.addEventListener('click', onClickFn, true);
p.addEventListener('click', onClickFn, true);

输出如下:

js 复制代码
DIV 1
P 1

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

IE事件模型

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

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

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

text 复制代码
attachEvent(eventType, handler)

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

text 复制代码
detachEvent(eventType, handler)

举个例子:

js 复制代码
var btn = document.getElementById('.btn');
btn.attachEvent('onclick', showMessage);
btn.detachEvent('onclick', showMessage);

总结

在本篇博客中,我们一起探索了JavaScript事件模型的四大概念:事件与事件流、原始事件模型、标准事件模型、IE事件模型。JavaScript是一门非常强大且广泛应用的编程语言。掌握了这些基本的语法和概念,你已经具备了入门JavaScript编程的基础。未来,你将能够创建更加交互性的网页,实现更多惊艳的动态效果,甚至搭建出属于自己的Web应用。但这只是一个开始,还有许多更深入的主题等待你去探索。

后续我们这个前端专栏还会讲述作用域、事件模型、内置对象、垃圾回收、js算法技巧、Vue入门实战、React实战、前端面试题等等文章,如果您感兴趣的话,欢迎点赞三连并关注我以及我的前端专栏,我们下期文章再见。

相关推荐
花生侠7 分钟前
记录:前端项目使用pnpm+husky(v9)+commitlint,提交代码格式化校验
前端
猿榜8 分钟前
魔改编译-永久解决selenium痕迹(二)
javascript·python
阿幸软件杂货间12 分钟前
阿幸课堂随机点名
android·开发语言·javascript
一涯14 分钟前
Cursor操作面板改为垂直
前端
我要让全世界知道我很低调21 分钟前
记一次 Vite 下的白屏优化
前端·css
threelab21 分钟前
three案例 Three.js波纹效果演示
开发语言·javascript·ecmascript
1undefined223 分钟前
element中的Table改造成虚拟列表,并封装成hooks
前端·javascript·vue.js
蓝倾1 小时前
淘宝批量获取商品SKU实战案例
前端·后端·api
comelong1 小时前
Docker容器启动postgres端口映射失败问题
前端
花海如潮淹1 小时前
硬件产品研发管理工具实战指南
前端·python