import dispathEvent from '../utils/dispathEvent'; import each from '../utils/each'; import callFn from '../utils/callFn'; export default class EventModule { /** * 事件对象 * @memberof EventModule */ private __listenEvents: object|undefined = undefined; /** * 派发自定义的DOM事件 * @param {HTMLElement|Window|Document} target 目标事件对象 * @param {String} eventType 事件类型 * @param {Object} options 选项 */ $dispathEvent (target: HTMLElement|Window|Document, eventType: string, options: any) { return dispathEvent(target, eventType, options); } /** * 监听事件 * @param {string|string[]|undefined} events 事件列表 * @param {Function} fn 回调方法 * @param {Boolean} priority 事件优先级 * @returns {Boolean} 监听是否成功 */ $on (events: string|string[]|undefined, fn: Function|undefined, priority: boolean): boolean { const _that = this; events = _that._filterEvents(events); if (!events || events.length <= 0 || typeof fn !== 'function') { return false; } let _listenEvents: object|undefined = _that.__listenEvents; each(events, (evtName: string) => { if (evtName) { let _fnName: string = priority ? 'unshift' : 'push'; _listenEvents = _listenEvents || {}; let _eventsList: Array = _listenEvents[evtName] = _listenEvents[evtName] || []; _eventsList[_fnName](fn); } }); _that.__listenEvents = _listenEvents; return true; } /** * 解除事件监听 * @param {string|string[]|undefined} events 事件列表 * @param {Function} fn 回调方法 * @returns {Boolean} 解除是否成功 */ $off (events: string|string[]|undefined, fn: Function|undefined): boolean { const _that = this; events = _that._filterEvents(events); let _listenEvents: object|undefined = _that.__listenEvents; if (!events || events.length <= 0 || !_listenEvents) { return false; } each(events, (evtName: string) => { if (!_listenEvents || !_listenEvents[evtName]) { return; } if (!fn && typeof _listenEvents[evtName] !== 'undefined') { delete _listenEvents[evtName]; } else { let _fnList = _listenEvents[evtName] || []; _fnList = _fnList.filter((fnItem: any) => { return !fnItem || !(fnItem === fn || (fnItem._f7Proxy && fnItem._f7Proxy === fn)); }); _listenEvents[evtName] = _fnList; } }); return true; } /** * 监听一次事件 * @param {string|string[]|undefined} events 事件类型 * @param {Function|undefined} fn 回调方法 * @param {Boolean} priority 事件优先级 * @returns {Boolean} */ $once (events: string|string[]|undefined, fn: Function|undefined, priority: boolean): boolean { const _that = this; events = _that._filterEvents(events); if (!events || events.length <= 0 || typeof fn !== 'function') { return false; } _proxyFn.f7Proxy = fn; return _that.$on(events, _proxyFn, priority); /** * 代理的方法 * @param {any[]} args 调用参数 */ function _proxyFn (...args: any[]) { _that.$off(events, _proxyFn); if (_proxyFn.f7Proxy) { delete _proxyFn.f7Proxy; } callFn(fn, args); } } /** * 冒泡事件 * @param {Array}} args 参数 * @returns {Boolean} */ $emit(...args: Array): boolean { const _that = this; let _listenEvents = _that.__listenEvents; if (!args || args.length <= 0 || !_listenEvents) { return false; } let _events: string|string[]|undefined; let _data: any; let _context: any; if (args[0] instanceof Object) { let _data: any = args[0]; _events = _data.events; _data = [_data.data]; _context = _data.context; } else { _events = args[0]; _data = args.slice(1); } _events = _that._filterEvents(_events); if (!_events || _events.length <= 0) { return false; } each(_events, (evtName: string) => { if (!evtName || !_listenEvents) { return; } let _fnList = _listenEvents[evtName] || []; each(_fnList, (fn: Function) => { callFn(fn, _data, _context); }); }); return true; } /** * 过滤事件类型 * @param {String|String[]|undefined} events 事件类型 * @returns {String[]} */ _filterEvents (events: string|string[]|undefined): string[]|undefined { let _res: string[]|undefined; if (events) { if (typeof events === 'string') { _res = events.split(' '); } else if (events instanceof Array) { _res = events; } } return _res; } }