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.html
,index.js
,request.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();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
2022-07-21 基于WebGL的方式使用OpenLayers