探索 JavaScript 事件机制(二):如何自定义事件

news/2024/10/24 4:48:34/

前言

在上篇文章中,我们了解了 JavaScript 的事件机制是怎么回事:从事件冒泡到事件捕获,再到事件委托。这次我们要更进一步,聊聊如何在 JavaScript 中自定义事件。这玩意儿可是前端开发中的一把利器,学会之后,你就可以为自己的应用增加更多的互动性和灵活性。

历史文章

探索 JavaScript 事件机制(一)从基础概念到实战应用

什么是自定义事件?

我们在开发过程中,常常会碰到一些场景,用原生的浏览器事件(如点击、滚动等)并不能完全满足需求。这时我们就需要“自定义事件”,它就像我们自己定义的一套规则,想啥时候触发就啥时候触发。

自定义事件的基本方法

JavaScript 提供了 CustomEvent 构造函数,让我们可以轻松创建自定义事件。下面是创建和触发自定义事件的基本步骤:

  1. 创建事件: 使用 CustomEvent 构造函数。
  2. 触发事件: 使用元素的 dispatchEvent 方法。
  3. 监听事件: 使用 addEventListener 监听自定义事件。

自定义事件的创建与使用

为了让大家更直观地理解,我们来通过一个小例子演示。假设我们有一个计数器,当计数达到某个值时,我们想触发一个自定义事件来通知系统。

第一步:创建自定义事件

// 创建一个名为 ‘countReached’ 的自定义事件

let countReachedEvent = new CustomEvent('countReached', {detail: { // detail 属性可以用来传递数据message: '计数达到指定值!',time: new Date()}
});

第二步:监听自定义事件

// 选择要监听事件的元素,这里假设是一个按钮
let button = document.getElementById('myButton');// 为按钮添加自定义事件的监听器
button.addEventListener('countReached', function(event) {console.log(event.detail.message); // 输出: 计数达到指定值!console.log('事件触发时间:', event.detail.time);
});

第三步:触发自定义事件

// 定义一个计数器变量
let count = 0;// 模拟计数器的增加
function incrementCounter() {count++;console.log('当前计数:', count);// 当计数达到 5 时,触发自定义事件if (count === 5) {button.dispatchEvent(countReachedEvent);}
}

// 假设这个函数被某个其它事件(比如按钮点击)调用

document.getElementById('incrementButton').addEventListener('click', incrementCounter);

完整代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>自定义事件示例</title>
</head>
<body><button id="incrementButton">增加计数</button><button id="myButton">监听自定义事件</button><script>// 创建一个名为 'countReached' 的自定义事件let countReachedEvent = new CustomEvent('countReached', {detail: {message: '计数达到指定值!',time: new Date()}});// 选择要监听事件的元素let button = document.getElementById('myButton');// 为按钮添加自定义事件的监听器button.addEventListener('countReached', function(event) {console.log(event.detail.message);console.log('事件触发时间:', event.detail.time);});// 定义一个计数器变量let count = 0;// 模拟计数器的增加function incrementCounter() {count++;console.log('当前计数:', count);if (count === 5) {button.dispatchEvent(countReachedEvent);}}// 按钮点击事件document.getElementById('incrementButton').addEventListener('click', incrementCounter);</script>
</body>
</html>

在上面的例子中,我们已经看到了如何创建和使用自定义事件。接下来,我们再扩展一些实用的技巧和高级用法,让你在实际项目中更得心应手。

高级用法:事件传播与事件目标

在事件机制中,我们需要了解事件是如何从目标元素传播(冒泡或捕获)的。自定义事件同样可以利用这种机制。我们可以指定事件是否冒泡以及是否可以被取消。

冒泡与取消

默认情况下,自定义事件是不冒泡的,但我们可以通过配置选项来改变这一行为。

let bubblingEvent = new CustomEvent('bubblingEvent', {bubbles: true, // 允许事件冒泡cancelable: true, // 允许事件取消detail: {message: '这个事件会冒泡!',time: new Date()}
});

接着,我们可以注册多个事件监听器,分别在不同的 DOM 层次上监听这个事件。

<div id="parent"><div id="child"><button id="bubblingButton">触发冒泡事件</button></div>
</div><script>// 获取 DOM 元素let parent = document.getElementById('parent');let child = document.getElementById('child');let bubblingButton = document.getElementById('bubblingButton');// 为父元素添加事件监听器parent.addEventListener('bubblingEvent', function(event) {console.log('父元素捕获到事件:', event.detail.message);});// 为子元素添加事件监听器child.addEventListener('bubblingEvent', function(event) {console.log('子元素捕获到事件:', event.detail.message);});// 触发事件bubblingButton.addEventListener('click', function() {bubblingButton.dispatchEvent(bubblingEvent);});
</script>

在这个例子中,当我们点击按钮时,自定义事件会从按钮冒泡到它的父元素。父元素和子元素的事件监听器都会被触发,这就展示了事件冒泡的强大之处。

取消事件

有时候,我们可能需要在事件传播的过程中取消事件。这个时候,我们可以利用 event.preventDefault() 和 event.stopPropagation() 方法。下面是一个例子:

// 创建可以取消的事件
let cancelableEvent = new CustomEvent('cancelableEvent', {bubbles: true,cancelable: true,detail: {message: '你可以取消这个事件',time: new Date()}
});// 父元素
parent.addEventListener('cancelableEvent', function(event) {if (!event.defaultPrevented) {console.log('父元素捕获到事件:', event.detail.message);}
});// 子元素
child.addEventListener('cancelableEvent', function(event) {// 取消事件event.preventDefault();console.log('子元素取消了事件:', event.detail.message);
});// 按钮点击触发事件
bubblingButton.addEventListener('click', function() {bubblingButton.dispatchEvent(cancelableEvent);
});

在这个例子中,子元素的事件监听器会取消事件的默认行为,所以父元素的事件监听器不会接收到这个事件。

应用场景

表单验证

在复杂的表单验证中,我们常常需要在某个字段验证成功或失败时通知其他部分。自定义事件可以很方便地实现这一点。

let form = document.getElementById('myForm');
let input = document.getElementById('myInput');

// 创建自定义事件

let validationEvent = new CustomEvent('fieldValidated', {detail: {field: 'myInput',valid: false,message: '输入不合法'}
});

// 表单监听验证事件

form.addEventListener('fieldValidated', function(event) {if (!event.detail.valid) {console.log('验证失败:', event.detail.message);} else {console.log('验证成功');}
});

// 模拟验证过程

input.addEventListener('blur', function() {if (input.value === '') {input.dispatchEvent(validationEvent);}
});
AJAX 请求完成通知

在前端开发中,AJAX 请求完成后,需要更新页面的其他部分,这时自定义事件就变得非常有用。

let ajaxEvent = new CustomEvent('ajaxComplete', {detail: {message: 'AJAX 请求已完成',data: { /* 返回的数据 */ }}
});

// 监听 AJAX 完成事件

document.addEventListener('ajaxComplete', function(event) {console.log(event.detail.message);// 更新页面部分// updatePage(event.detail.data);
});

// 模拟 AJAX 请求

function mockAjaxRequest() {setTimeout(function() {document.dispatchEvent(ajaxEvent);}, 1000);
}

// 模拟按钮点击发送 AJAX 请求

let ajaxButton = document.getElementById('ajaxButton');
ajaxButton.addEventListener('click', mockAjaxRequest);

总结

自定义事件在前端开发中提供了极大的灵活性,可以帮助我们简化代码逻辑,提升代码的可维护性。通过本文的学习,希望你能够更好地理解和使用自定义事件,为你的项目增添更多的互动和动态效果。


http://www.ppmy.cn/news/1541517.html

相关文章

大厂面试真题-了解云原生吗,简单说一下docker和k8s

K8s&#xff08;Kubernetes&#xff09;和Docker都是容器化技术中的关键组件&#xff0c;但它们各自扮演着不同的角色。以下是对这两者的详细解析&#xff1a; 一、Docker Docker是一个开源的容器化平台&#xff0c;它允许开发人员将应用程序及其依赖项打包为一个独立的镜像&…

java项目篇-用户脱敏展示

用户敏感信息脱敏展示 定义手机号和证件号的 Jackson 自定义序列化器&#xff0c;并在对应需要脱敏的敏感字段上指定自定义序列化器。在进行指定的需要脱敏的字段&#xff08;身份证号&#xff0c;手机号&#xff0c;银行卡号等&#xff09;序列化的时候&#xff0c;该字段自动…

智能去毛刺:2D视觉引导机器人如何重塑制造业未来

机器人技术已经深入到各个工业领域中&#xff0c;为制造业带来了前所未有的变革。其中&#xff0c;2D视觉引导机器人技术以其精准、高效的特点&#xff0c;在去毛刺工艺中发挥着越来越重要的作用。本文将为您介绍2D视觉引导机器人技术的基本原理及其在去毛刺工艺中的应用&#…

[ABC253E] Distance Sequence(线性dp且利用前缀和进行优化)

思路&#xff1a;根据数据范围还有题目所处的位置我们可以联想到该题可以用dp来求解&#xff0c;我们设dp[i][j]代表第i个数为j时的方案数&#xff0c;dp[i][j]应为dp[i - 1][t] (t < j - k) 和dp[i - 1][j k]转移过来,如果我们不做任何优化的话n* m * n是肯定超时的&#…

【个人同步与备份】电脑(Windows)与手机/平板(Android)之间文件同步

文章目录 1. syncthing软件下载2. syncthing的使用2.1. 添加设备2.1.1. syncthing具备设备发现功能&#xff0c;因此安装好软件&#xff0c;只需确认设备信息是否对应即可2.1.2. 如果没有发现到&#xff0c;可以通过设备ID连接2.1.3. 设置GUI身份验证用户&#xff0c;让无关设备…

python装饰器property的使用

使用 Python 的 property 装饰器管理类属性 在 Python 中&#xff0c;property 装饰器是一个非常有用的工具&#xff0c;它允许我们将一个方法转换为属性调用。这样&#xff0c;我们就可以像访问对象的属性一样来调用该方法&#xff0c;而不需要使用括号。这通常用于封装数据&…

w~自动驾驶合集9

我自己的原文哦~ https://blog.51cto.com/whaosoft/12320882 #自动驾驶数据集全面调研 自动驾驶技术在硬件和深度学习方法的最新进展中迅速发展&#xff0c;并展现出令人期待的性能。高质量的数据集对于开发可靠的自动驾驶算法至关重要。先前的数据集调研试图回顾这些数据集&…

【iOS】YYModel

目录 什么是YYModel &#xff1f; 如何使用YYModel &#xff1f; 最简单的Model 与网络请求结合 属性为容器类的Model 白名单和黑名单 Model的嵌套 结语 什么是YYModel &#xff1f; YYModel是一个用于 iOS 和 macOS 开发的高性能的模型框架&#xff0c;主要用于对象和…