addEventListener 和 attachEvent 使用
在 JavaScript 中,addEventListener
和 attachEvent
都是用来向元素添加事件处理程序的方法,但两者之间存在一些区别。
- addEventListener:
addEventListener
是标准的 DOM 方法,适用于现代的浏览器。- 语法:
element.addEventListener(event, function, useCapture)
- 第一个参数是事件类型,第二个参数是事件处理函数,第三个参数是一个可选的布尔值用于指定事件是在捕获阶段还是冒泡阶段处理。
- 可以同时添加多个相同类型的事件处理程序,它们按照添加顺序依次执行。
- 通过
removeEventListener
方法可以移除事件处理程序。
示例:
element.addEventListener('click', myFunction);
- attachEvent:
attachEvent
是 IE 浏览器专有的方法,仅适用于旧版本的 Internet Explorer(IE8 及以下)。- 语法:
element.attachEvent(event, function)
- 不支持捕获阶段的概念,所有事件处理函数都会在冒泡阶段执行。
- 只能同时添加一个相同类型的事件处理程序,重复添加会覆盖之前的处理程序。
- 通过
detachEvent
方法可以移除事件处理程序。
示例:
element.attachEvent('onclick', myFunction);
在现代的 Web 开发中,建议优先使用 addEventListener
方法来添加事件处理程序,因为它具有更好的兼容性和更灵活的特性。如果需要兼容旧版本的 IE 浏览器,可以在代码中做相应的兼容性处理,例如通过判断浏览器类型来选择使用哪种方法来添加事件处理程序。
原生的自定义事件
创建自定义事件
原生自定义事件有三种写法:
- 使用
Event
let myEvent = new Event('event_name');
- 使用
customEvent
(可以传参数)
let myEvent = new CustomEvent('event_name', {
detail: {
// 将需要传递的参数放到这里
// 可以在监听的回调函数中获取到:event.detail
}
})
- 使用
document.createEvent('CustomEvent')和initCustomEvent()
let myEvent = document.createEvent('CustomEvent');// 注意这里是为'CustomEvent'
myEvent.initEvent(
// 1. event_name: 事件名称
// 2. canBubble: 是否冒泡
// 3. cancelable: 是否可以取消默认行为
)
createEvent
:创建一个事件initEvent
:初始化一个事件
可以看到,initEvent
可以指定3个参数。
(有些文章中会说还有第四个参数detail
,但是我查看了W3C
上并没有这个参数,而且实践了一下也没有效果)
事件的监听
自定义事件的监听其实和普通事件的一样,使用addEventListener
来监听:
button.addEventListener('event_name', function (e) {})
事件的触发
触发自定义事件使用dispatchEvent(myEvent)
。
注意⚠️,这里的参数是要自定义事件的对象(也就是myEvent
),而不是自定义事件的名称('myEvent'
)
案例
来看个案例吧:
// 1.
// let myEvent = new Event('myEvent');
// 2.
// let myEvent = new CustomEvent('myEvent', {
// detail: {
// name: 'lindaidai'
// }
// })
// 3.
let myEvent = document.createEvent('CustomEvent');
myEvent.initEvent('myEvent', true, true)
let btn = document.getElementsByTagName('button')[0]
btn.addEventListener('myEvent', function (e) {
console.log(e)
console.log(e.detail)
})
setTimeout(() => {
btn.dispatchEvent(myEvent)
}, 2000)
JavaScript 原生提供了自定义事件的功能,允许开发者创建自定义的事件类型并在代码中进行触发和处理。
以下是使用 JavaScript 原生进行自定义事件的一般步骤:
-
创建自定义事件类型:使用
Event()
构造函数创建一个新的事件对象,可以使用new Event(eventName)
进行创建,其中eventName
是自定义事件的名称。 -
注册事件处理程序:使用
addEventListener()
方法将事件处理程序附加到特定的元素或文档上,以便在触发自定义事件时能够捕获并处理它。 -
触发自定义事件:使用
dispatchEvent()
方法在适当的时候触发自定义事件。可以使用element.dispatchEvent(event)
进行手动触发,其中element
是事件目标元素,event
是之前创建的自定义事件对象。
下面是一个简单的示例,展示如何创建、注册和触发自定义事件:
// 创建自定义事件
var myEvent = new Event('myEvent');
// 注册事件处理程序
document.addEventListener('myEvent', function(e) {
console.log('Custom event triggered!');
});
// 触发自定义事件
document.dispatchEvent(myEvent);
当代码执行到 document.dispatchEvent(myEvent)
时,会触发注册在 document
上的 myEvent
事件处理程序,并输出 “Custom event triggered!” 到控制台。
通过使用 JavaScript 原生的自定义事件功能,可以在开发中实现更灵活、可扩展的事件处理机制,以满足特定的需求。
什么场景下使用它
在 JavaScript 中,使用原生自定义事件可以在一些特定的场景下提供更灵活的事件通信机制。以下是一些适合使用原生自定义事件的场景:
-
组件通信:当多个组件需要进行解耦合、相互通信时,可以使用自定义事件来进行跨组件通信,实现组件之间的数据传递和交互。
-
插件扩展:在开发插件或库时,可以使用自定义事件来提供插件的扩展能力,使用户能够在特定的时机自定义处理逻辑。
-
模块化开发:在模块化的 JavaScript 应用程序中,可以使用自定义事件来实现模块之间的通信,例如在模块初始化、销毁或状态改变时进行通知。
-
异步操作:在异步操作完成后,可以通过自定义事件来通知其他部分代码操作已完成,例如在 Ajax 请求返回数据后触发一个自定义事件来处理数据更新。
-
解耦合:使用自定义事件可以降低组件之间的耦合度,组件只需关心自己感兴趣的事件,而不需要直接调用其它组件的方法。
-
事件代理:在一些动态生成的内容中,可以使用自定义事件代理来处理事件,减少重复绑定事件处理函数的情况。
总的来说,使用原生自定义事件的场景通常是在需要实现组件间的松耦合、模块化开发、跨模块通信等情况下,以提高代码的可维护性、可扩展性和灵活性。当传统的事件监听机制无法满足需求时,原生自定义事件就成为一个非常有用的解决方案。
例子
当使用原生自定义事件进行组件通信时,以下是一个基本的示例代码:
// 定义自定义事件
const event = new Event('customEvent');
// 组件A
const componentA = {
init() {
// 组件A监听自定义事件
document.addEventListener('customEvent', this.handleEvent);
},
handleEvent(event) {
console.log('Component A is handling custom event:', event);
// 处理事件的逻辑
},
destroy() {
// 组件A移除自定义事件监听器
document.removeEventListener('customEvent', this.handleEvent);
}
};
// 组件B
const componentB = {
handleClick() {
console.log('Component B is triggering custom event');
// 触发自定义事件
document.dispatchEvent(event);
}
};
// 初始化组件A
componentA.init();
// 使用组件B触发自定义事件
componentB.handleClick();
// 销毁组件A
componentA.destroy();
在上述示例中,组件 A 使用 document.addEventListener
方法监听名为 “customEvent” 的自定义事件,并提供了一个事件处理函数 handleEvent
。在组件 B 中,通过 document.dispatchEvent
方法触发了 “customEvent” 自定义事件。当自定义事件被触发时,组件 A 的事件处理函数就会执行,并进行相应的逻辑处理。
通过使用原生自定义事件,组件 A 和组件 B 之间可以实现解耦合,它们不需要直接调用彼此的方法,而是通过自定义事件来进行通信。这样的设计模式有助于提高代码的可维护性和扩展性,使组件之间的耦合度更低。