All files / utils bindEvent.ts

100% Statements 4/4
100% Branches 0/0
100% Functions 3/3
100% Lines 3/3

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83                                                                                                                                                          12x 13x 13x      
/* eslint-disable prefer-rest-params, prefer-spread */
import { AnyFunction } from '../types'
 
/**
 * 绑定事件函数。
 *
 * @public
 * @param type 事件类型
 * @param callback 事件回调
 * @param options 事件选项
 * @returns 返回事件解绑函数
 */
export type BindEventFunction<T> = <
  // prettier-ignore
  E extends
    // window
    T extends typeof window
    ? WindowEventMap
 
    // 打包时报错: Cannot find name 'HTMLVideoElementEventMap'
    // video
    // : T extends HTMLVideoElement
    // ? HTMLVideoElementEventMap
 
    // media
    : T extends HTMLMediaElement
    ? HTMLMediaElementEventMap
 
    // body
    : T extends HTMLBodyElement
    ? HTMLBodyElementEventMap
 
    // frame set
    : T extends HTMLFrameSetElement
    ? HTMLFrameSetElementEventMap
 
    // FileReader
    : T extends FileReader
    ? FileReaderEventMap
 
    // WebSocket
    : T extends WebSocket
    ? WebSocketEventMap
 
    // svg element
    : T extends SVGElement
    ? SVGElementEventMap
 
    // html element
    : T extends HTMLElement
    ? HTMLElementEventMap
 
    // others
    : Record<string, any>,
  K extends keyof E
>(
  type: K,
  callback: (this: T, ev: E[K]) => any,
  options?: boolean | AddEventListenerOptions,
) => () => any
 
/**
 * 绑定事件。
 *
 * @public
 * @param target 事件绑定的目标
 * @returns 返回事件绑定函数
 * @example
 * ```typescript
 * const bindWindowEvent = bindEvent(window)
 * const unbindClick = bindWindowEvent('click', console.log)
 * const unbindScroll = bindWindowEvent('scroll', console.log)
 * ```
 */
export function bindEvent<
  T extends Record<'addEventListener' | 'removeEventListener', AnyFunction>
>(target: T): BindEventFunction<T> {
  return (type, callback, options) => {
    target.addEventListener(type, callback, options)
    return () => target.removeEventListener(type, callback, options)
  }
}