112 lines
2.9 KiB
JavaScript
112 lines
2.9 KiB
JavaScript
// 事件安全处理工具
|
|
export class EventSafety {
|
|
// 创建安全的事件对象
|
|
static createSafeEvent(originalEvent = {}) {
|
|
const safeEvent = {
|
|
type: originalEvent.type || 'unknown',
|
|
timeStamp: originalEvent.timeStamp || Date.now(),
|
|
detail: originalEvent.detail || {},
|
|
// 安全的目标对象
|
|
get target() {
|
|
return EventSafety.createSafeTarget(originalEvent.target)
|
|
},
|
|
get currentTarget() {
|
|
return EventSafety.createSafeTarget(originalEvent.currentTarget)
|
|
},
|
|
// 安全的 matches 方法
|
|
matches(selector) {
|
|
return EventSafety.safeMatches(originalEvent.target, selector)
|
|
}
|
|
}
|
|
|
|
return new Proxy(safeEvent, {
|
|
get(obj, prop) {
|
|
// 防止访问不存在的属性
|
|
if (prop in obj) {
|
|
return obj[prop]
|
|
}
|
|
return undefined
|
|
}
|
|
})
|
|
}
|
|
|
|
// 创建安全的目标对象
|
|
static createSafeTarget(target) {
|
|
if (!target || typeof target !== 'object') {
|
|
return EventSafety.getFallbackTarget()
|
|
}
|
|
|
|
const safeTarget = {
|
|
// 基础属性
|
|
tagName: target.tagName || '',
|
|
id: target.id || '',
|
|
className: target.className || '',
|
|
// 安全的方法
|
|
matches: (selector) => EventSafety.safeMatches(target, selector),
|
|
// 数据集
|
|
dataset: target.dataset || {}
|
|
}
|
|
|
|
return safeTarget
|
|
}
|
|
|
|
// 安全的 matches 检查
|
|
static safeMatches(element, selector) {
|
|
if (!element || typeof element.matches !== 'function') {
|
|
return false
|
|
}
|
|
|
|
try {
|
|
return element.matches(selector)
|
|
} catch (error) {
|
|
console.warn('matches 检查失败:', error)
|
|
return false
|
|
}
|
|
}
|
|
|
|
// 回退目标对象
|
|
static getFallbackTarget() {
|
|
return {
|
|
tagName: '',
|
|
id: '',
|
|
className: '',
|
|
matches: () => false,
|
|
dataset: {}
|
|
}
|
|
}
|
|
|
|
// 包装事件处理器
|
|
static wrapEventHandler(handler, options = {}) {
|
|
return function(event) {
|
|
try {
|
|
// 创建安全的事件对象
|
|
const safeEvent = EventSafety.createSafeEvent(event)
|
|
return handler.call(this, safeEvent)
|
|
} catch (error) {
|
|
console.error('事件处理错误:', error)
|
|
// 可选的错误处理
|
|
if (options.onError) {
|
|
options.onError(error, event, this)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 验证事件类型
|
|
static isValidEventType(event, expectedType) {
|
|
return event && event.type === expectedType
|
|
}
|
|
|
|
// 提取安全的事件数据
|
|
static extractEventData(event, fields = ['type', 'timeStamp', 'detail']) {
|
|
const result = {}
|
|
|
|
fields.forEach(field => {
|
|
if (event && field in event) {
|
|
result[field] = event[field]
|
|
}
|
|
})
|
|
|
|
return result
|
|
}
|
|
} |