createSharedKeyboardCenter
创建共享的键盘事件中心,基于单例模式,只在第一次使用时添加键盘监听事件。
前置依赖
依赖参数
| 参数名 | 类型 | 说明 |
|---|---|---|
deps.addEventListener | Window['addEventListener'] | 添加事件监听函数 |
deps.removeEventListener | Window['removeEventListener'] | 移除事件监听函数 |
deps.log | Console['log'] | 日志输出函数 |
deps.error | Console['error'] | 错误日志函数 |
deps.warn | Console['warn'] | 警告日志函数 |
环境要求
- 浏览器环境: 需要 Window 对象的
addEventListener和removeEventListener方法 - 控制台对象: 需要 console 对象
typescript
const deps = {
addEventListener: window.addEventListener,
removeEventListener: window.removeEventListener,
log: console.log,
error: console.error,
warn: console.warn
}函数签名
typescript
function createSharedKeyboardCenter(
deps: KeyboardCenterDeps
): KeyboardCenter
interface KeyboardCenterDeps {
addEventListener: Window['addEventListener']
removeEventListener: Window['removeEventListener']
log: Console['log']
error: Console['error']
warn: Console['warn']
}
interface KeyboardCenter {
subscribe(listener: KeyboardEventListener): () => void
unsubscribe(listener: KeyboardEventListener): void
getListenerCount(): number
isInitialized(): boolean
}
type KeyboardEventListener = (event: KeyboardEvent) => void参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
deps | KeyboardCenterDeps | 是 | 依赖注入对象 |
返回值
| 类型 | 说明 |
|---|---|
KeyboardCenter | 键盘事件中心实例(单例) |
KeyboardCenter
| 方法名 | 类型 | 说明 |
|---|---|---|
subscribe | (listener: KeyboardEventListener) => () => void | 订阅键盘事件,返回取消订阅函数 |
unsubscribe | (listener: KeyboardEventListener) => void | 取消订阅键盘事件 |
getListenerCount | () => number | 获取当前订阅者数量 |
isInitialized | () => boolean | 检查是否已添加全局键盘监听 |
工作原理
- 单例模式:全局共享一个键盘事件中心实例,多次调用
createSharedKeyboardCenter返回同一个实例 - 懒加载:只在第一次调用
subscribe()时添加全局的keydown和keyup监听 - 订阅机制:支持多个订阅者,每个订阅者都会收到所有键盘事件
- 持久监听:即使移除所有订阅者,全局键盘监听仍然保持,不会主动移除
- 依赖注入:所有环境依赖通过参数传入,不直接使用全局对象
使用示例
基础使用
typescript
import { createSharedKeyboardCenter } from 'zcw-shared/functions/dom/createSharedKeyboardCenter'
// 创建键盘事件中心(单例)
const center = createSharedKeyboardCenter({
addEventListener: window.addEventListener.bind(window),
removeEventListener: window.removeEventListener.bind(window),
log: console.log,
error: console.error,
warn: console.warn
})
// 订阅键盘事件
const unsubscribe = center.subscribe((event) => {
console.log('按键:', event.key)
})
// 取消订阅
unsubscribe()多个订阅者
typescript
import { createSharedKeyboardCenter } from 'zcw-shared/functions/dom/createSharedKeyboardCenter'
const center = createSharedKeyboardCenter({
addEventListener: window.addEventListener,
removeEventListener: window.removeEventListener,
log: console.log,
error: console.error,
warn: console.warn
})
// 订阅者 1
const unsubscribe1 = center.subscribe((event) => {
console.log('订阅者 1 收到:', event.key)
})
// 订阅者 2
const unsubscribe2 = center.subscribe((event) => {
console.log('订阅者 2 收到:', event.key)
})
// 取消订阅者 1
unsubscribe1()
// 订阅者 2 仍然可以接收到键盘事件在 Vue 组件中使用
typescript
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue'
import { createSharedKeyboardCenter } from 'zcw-shared/functions/dom/createSharedKeyboardCenter'
const center = createSharedKeyboardCenter({
addEventListener: window.addEventListener,
removeEventListener: window.removeEventListener,
log: console.log,
error: console.error,
warn: console.warn
})
const keys: string[] = []
const handleKeyPress = (event: KeyboardEvent) => {
keys.push(event.key)
console.log('当前按键:', event.key)
}
onMounted(() => {
center.subscribe(handleKeyPress)
})
onUnmounted(() => {
center.unsubscribe(handleKeyPress)
})
</script>快捷键监听
typescript
import { createSharedKeyboardCenter } from 'zcw-shared/functions/dom/createSharedKeyboardCenter'
const center = createSharedKeyboardCenter({
addEventListener: window.addEventListener,
removeEventListener: window.removeEventListener,
log: console.log,
error: console.error,
warn: console.warn
})
center.subscribe((event) => {
// 监听 Ctrl+S 或 Cmd+S(保存)
if ((event.key === 's' && event.ctrlKey) || (event.key === 's' && event.metaKey)) {
event.preventDefault()
console.log('保存文件')
}
// 监听 Escape 键
if (event.key === 'Escape') {
console.log('取消操作')
}
})注意事项
- 单例特性:无论调用多少次
createSharedKeyboardCenter,都会返回同一个实例 - 持久监听:全局键盘监听会在添加后一直保持,即使移除所有订阅者也不会主动移除
- 性能优化:只有一个全局键盘监听器,不会因为多个订阅者而添加多个监听器
- 被动监听:事件监听使用
passive: true选项,提升滚动性能 - 错误处理:监听器执行错误不会影响其他订阅者