feat(core): 增强核心事件通讯总线,增强跨组件交互能力
This commit is contained in:
133
common/js/dom-event-bridge.js
Normal file
133
common/js/dom-event-bridge.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Uniapp DOM 事件桥接类,用于将 DOM 事件桥接到 EventBus
|
||||
* 支持将 DOM 事件转换为 EventBus 事件,可配置是否阻止默认行为和停止传播
|
||||
*
|
||||
* @author ZFSun <lauer3912@gmail.com>
|
||||
* @version 1.0.0
|
||||
* @createTime 2023-08-10
|
||||
*/
|
||||
|
||||
class DomEventBridge {
|
||||
constructor() {
|
||||
this.eventBus = null
|
||||
this.domListeners = new Map()
|
||||
}
|
||||
|
||||
// 设置 EventBus 实例
|
||||
setEventBus(eventBus) {
|
||||
this.eventBus = eventBus
|
||||
}
|
||||
|
||||
// 桥接 DOM 事件到 EventBus
|
||||
bridgeDomEvent(domEventName, eventBusEventName, options = {}) {
|
||||
const handler = (domEvent) => {
|
||||
if (!this.eventBus) return
|
||||
|
||||
// 创建 EventBus 兼容的事件对象
|
||||
const eventBusEvent = this.createEventBusEvent(domEvent, eventBusEventName)
|
||||
|
||||
// 触发 EventBus 事件
|
||||
const shouldContinue = this.eventBus.emit(eventBusEventName, eventBusEvent)
|
||||
|
||||
// 根据 EventBus 处理结果决定是否阻止 DOM 事件默认行为
|
||||
if (!shouldContinue && options.preventDefault) {
|
||||
domEvent.preventDefault()
|
||||
}
|
||||
|
||||
// 根据 EventBus 处理结果决定是否停止 DOM 事件传播
|
||||
if (!shouldContinue && options.stopPropagation) {
|
||||
domEvent.stopPropagation()
|
||||
}
|
||||
}
|
||||
|
||||
// 保存监听器引用以便清理
|
||||
const listenerKey = `${domEventName}-${eventBusEventName}`
|
||||
this.domListeners.set(listenerKey, handler)
|
||||
|
||||
// 添加 DOM 事件监听
|
||||
// #ifdef H5
|
||||
document.addEventListener(domEventName, handler, options)
|
||||
// #endif
|
||||
|
||||
return () => this.unbridgeDomEvent(domEventName, eventBusEventName)
|
||||
}
|
||||
|
||||
// 创建 EventBus 兼容的事件对象
|
||||
createEventBusEvent(domEvent, eventBusEventName) {
|
||||
return {
|
||||
type: eventBusEventName,
|
||||
domEvent: domEvent,
|
||||
originalEvent: domEvent,
|
||||
target: domEvent.target,
|
||||
currentTarget: domEvent.currentTarget,
|
||||
timestamp: Date.now(),
|
||||
|
||||
// EventBus 的取消方法
|
||||
preventDefault: function () {
|
||||
this._preventDefault = true
|
||||
},
|
||||
|
||||
stopPropagation: function () {
|
||||
this._stopPropagation = true
|
||||
},
|
||||
|
||||
// DOM 事件的代理方法
|
||||
stopImmediatePropagation: function () {
|
||||
domEvent.stopImmediatePropagation()
|
||||
},
|
||||
|
||||
get isDefaultPrevented() {
|
||||
return this._preventDefault || false
|
||||
},
|
||||
|
||||
get isPropagationStopped() {
|
||||
return this._stopPropagation || false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 取消桥接
|
||||
unbridgeDomEvent(domEventName, eventBusEventName) {
|
||||
const listenerKey = `${domEventName}-${eventBusEventName}`
|
||||
const handler = this.domListeners.get(listenerKey)
|
||||
|
||||
if (handler) {
|
||||
// #ifdef H5
|
||||
document.removeEventListener(domEventName, handler)
|
||||
// #endif
|
||||
this.domListeners.delete(listenerKey)
|
||||
}
|
||||
}
|
||||
|
||||
// 从 EventBus 触发 DOM 事件
|
||||
triggerDomEventFromEventBus(domEventName, detail = {}) {
|
||||
// #ifdef H5
|
||||
const event = new CustomEvent(domEventName, {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
detail: detail
|
||||
})
|
||||
|
||||
document.dispatchEvent(event)
|
||||
return !event.defaultPrevented
|
||||
// #endif
|
||||
|
||||
// #ifdef MP - WEIXIN
|
||||
// 小程序环境不支持 DOM 事件
|
||||
return true
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 清理所有桥接
|
||||
destroy() {
|
||||
for (const [listenerKey, handler] of this.domListeners) {
|
||||
const [domEventName] = listenerKey.split('-')
|
||||
// #ifdef H5
|
||||
document.removeEventListener(domEventName, handler)
|
||||
// #endif
|
||||
}
|
||||
this.domListeners.clear()
|
||||
}
|
||||
}
|
||||
|
||||
export default new DomEventBridge()
|
||||
Reference in New Issue
Block a user