JavaScript自定义事件

1. 引言

在Web中,事件,通常是指某个动作的完成,比如,鼠标点击、鼠标移动、键盘按下等

事件监听,通常是指监听某个动作,动作完成后触发相应的变化,如,鼠标点击按钮后弹出确认框

通过事件监听,当某个事件完成或者状态改变时,可以触发监听者的更新或预设行为,比如,点击按钮弹出确认框、窗口大小改变时网页内容也改变大小等

在软件工程中,这种设计模式叫观察者模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新

2. 内置事件

在Web中,事件的主体(即,可以触发与监听事件的对象)通常是DOM对象,如,Button、Div等

2.1 事件监听

事件监听是主要的应用场景

HTML和JS已经内置了大部分会出现的事件,经典的事件如点击事件,通常Button可以这样监听:

<body>
<button>按钮</button>
<script>
var btn = document.querySelector('button');
btn.onclick = function() {
console.log('click');
}
</script>
</body>

即设置on+<event name>属性的方式,设置对事件的监听

现在通常使用下面的方式实现监听:

<body>
<button>按钮</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
console.log('click');
});
</script>
</body>

浏览器中实现的详细的事件,可以从MDN中查询:Event - Web API 接口参考 | MDN (mozilla.org)

2.2 事件触发

通常事件触发是行为触发的,比如,鼠标去点击按钮触发

有时需要通过代码去主动触发,如何实现代码主动触发事件呢

经典的事件,通常DOM对象内置了主动触发的方法,如点击事件:

<body>
<button>按钮</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
console.log('click');
});
btn.click(); // 触发点击事件
</script>
</body>

如果DOM对象没有内置了主动触发的方法,可以使用下面这种方式:

<body>
<button>按钮</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
console.log('click');
});
btn.dispatchEvent(new Event('click')); // 触发click事件
</script>
</body>

3. 自定义事件

3.1 DOM对象

上述事件是浏览器内置所支持的,加入浏览器没有支持或者想自定义事件呢,比如,想监听数据加载,加载完成后对应的DOM元素刷新

这时可以设置一个名为dataLoaded的自定义事件(Custom Event),将DOM元素设置为监听者,然后加载数据后触发事件:

<body>
<div id="containter"></div>
<script>
const container = document.getElementById('containter');
container.addEventListener('dataLoaded', (e) => {
console.log(e.detail);
container.innerHTML = `<h1>${e.detail.name}</h1><p>${e.detail.age}</p>`
})
function load() {
// 模拟数据加载
const data = {
name: 'John',
age: 20
}
const event = new CustomEvent('dataLoaded', {
detail: data
})
container.dispatchEvent(event); // 触发dataLoaded事件
}
load();
</script>
</body>

CustomEvent的详细介绍可以参考:CustomEvent() - Web API 接口参考 | MDN (mozilla.org)

上述代码中,看上去这个事件机制用法是多余的,完全可以在加载数据后执行相应的更新函数即可,何必再套一层事件监听与事件触发呢

倒也不然,如下面这个例子,有三个文件,分别是index.htmlindex.jsrequest.js

index.html:

<body>
<div id="containter"></div>
<script>
const container = document.getElementById('containter');
container.addEventListener('dataLoaded', (e) => {
console.log(e.detail);
container.innerHTML = `<h1>${e.detail.name}</h1><p>${e.detail.age}</p>`
})
</script>
</body>

index.js:

const container = document.getElementById('containter');
container.addEventListener('dataLoaded', (e) => {
doSomething()
})
function doSomething(){
// ...
}

request.js:

function load() {
// 模拟数据加载
const data = {
name: 'John',
age: 20
}
const event = new CustomEvent('dataLoaded', {
detail: data
})
container.dispatchEvent(event);
}
load();

上述示例中,在数据加载后,其余各处会执行相应的函数,代码组织也更为易懂

3.2 JS对象

上面所述的均为DOM对象,JS中的对象能否监听事件呢

答曰,可以,需要继承EventTarget

EventTarget详细的API介绍可以参考MDN:EventTarget - Web API 接口参考 | MDN (mozilla.org)

下面是一个示例代码,展示了如何编写一个类,继承自EventTarget,并实现事件监听功能:

class MyObject extends EventTarget {
myMethod() {
// 在方法内部触发事件
this.dispatchEvent(new Event('myEvent'));
}
}
// 实例化对象
const obj = new MyObject();
// 添加事件监听器
obj.addEventListener('myEvent', myEventHandler);
// 事件处理函数
function myEventHandler(event) {
// 处理事件的逻辑
console.log('Event triggered:', event);
}
// 调用方法,触发事件
obj.myMethod();

4 .参考资料

[1] 事件参考 | MDN (mozilla.org)

[2] CustomEvent - Web API 接口参考 | MDN (mozilla.org)

[3] EventTarget - Web API 接口参考 | MDN (mozilla.org)

posted @   当时明月在曾照彩云归  阅读(207)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
历史上的今天:
2022-07-21 基于WebGL的方式使用OpenLayers
点击右上角即可分享
微信分享提示