ts中的dom元素和event事件类型声明

1, HTMLElement 和 Element

    <div id="divClick"></div>
     const docu = document.getElementById('divClick');
     const docu1 = document.querySelector('#divClick');

把鼠标分别放在docu和docu1上:


HTMLElement

HTMLElement 是 HTML 文档中某个元素的具体类型,该类型包含了所有 HTML 元素的共有属性和方法,如 CSSStyleDeclaration 和 EventTarget。

Element

Element 是 HTMLElement 的基本类型,它表示文档中任何类型的标记元素(如 div、span、p 等),包括非 HTML 元素。 Element 类型只包含最基本的属性(如 tagName 和 attributes)和方法(如 getAttribute() 和 setAttribute())。

HTMLElement 和 Element 两者区别

Element 是一个通用的基类,所有 Document 对象下的对象都继承自它。这个接口描述了所有相同种类的元素所普遍具有的方法和属性。一些接口继承自 Element 并且增加了一些额外功能的接口描述了具体的行为。例如, HTMLElement 接口是所有 HTML 元素的基本接口,而 SVGElement 接口是所有 SVG 元素的基础。大多数功能是在这个类的更深层级的接口中被进一步制定的。

HTMLElement是extends Element、然后额外增加一些额外的接口。
Element是所有元素的基类。

在node_modules下面的typescript/lib/lib.dom.d.ts:


interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEditable, GlobalEventHandlers, HTMLOrSVGElement {
        accessKey: string;
        readonly accessKeyLabel: string;
        autocapitalize: string;
        dir: string;
        draggable: boolean;
        hidden: boolean;
        inert: boolean;
        innerText: string;
        lang: string;
        readonly offsetHeight: number;
        readonly offsetLeft: number;
        readonly offsetParent: Element | null;
        readonly offsetTop: number;
        readonly offsetWidth: number;
        outerText: string;
        spellcheck: boolean;
        title: string;
        translate: boolean;
        attachInternals(): ElementInternals;
        click(): void;
        addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => 
                         any, options?: boolean | AddEventListenerOptions): void;
        addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
        removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => 
                         any, options?: boolean | EventListenerOptions): void;
        removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;

2. 具体的dom元素类型声明

虽然说每次获取dom结点,都可以通过设置类型为HTMLElement。但是有的时候也会有问题, 比如

<input type="text" value="hello">
    
    const input = document.querySelector('input[type=text]') as HTMLElement;
    console.log(input!.value);   // 类型“HTMLElement”上不存在属性“value”

这时候,我们就需要把它设置为更具体一点的dom类型。

      const input = document.querySelector('input[type=text]') as HTMLInputElement;
       console.log(input!.value);

设置为HTMLInputElement,TS不报错原因
typescript/lib/lib.dom.d.ts:


    interface HTMLInputElement extends HTMLElement {
         ...
        /** Gets or sets a string containing a regular expression that the user's input must match. */
        pattern: string;
        /** Gets or sets a text string that is displayed in an input field as a hint or prompt to users as the format or type of information 
            they need to enter.The text appears in an input field until the user puts focus on the field. */
        placeholder: string;
        readOnly: boolean;
        /** When present, marks an element that can't be submitted without a value. */
        required: boolean;
        selectionDirection: "forward" | "backward" | "none" | null;
        /** Gets or sets the end position or offset of a text selection. */
        selectionEnd: number | null;
        /** Gets or sets the starting position or offset of a text selection. */
        selectionStart: number | null;
        size: number;
        /** The address or URL of the a media resource that is to be considered. */
        src: string;
        /** Defines an increment or jump between values that you want to allow the user to enter. When used with the max and min attributes,
             lets you control the range and increment (for example, allow only even numbers) that the user can enter into an input field. */
        step: string;
        /** Returns the content type of the object. */
        type: string;
         /** Returns the value of the data at the cursor's current position. */
        value: string;
        ...
}

HTMLInputElement是继承HTMLElement的,基于HTMLElement进行扩展的
这里是moudles ts文件中的一些继承HTMLElement的类型


    interface HTMLElementTagNameMap {
        "a": HTMLAnchorElement;
        "abbr": HTMLElement;
        "address": HTMLElement;
        "applet": HTMLAppletElement;
        "area": HTMLAreaElement;
        "article": HTMLElement;
        "aside": HTMLElement;
        "audio": HTMLAudioElement;
        "b": HTMLElement;
        "base": HTMLBaseElement;
        "bdi": HTMLElement;
        "bdo": HTMLElement;
        "blockquote": HTMLQuoteElement;
        "body": HTMLBodyElement; 
        "br": HTMLBRElement;
        "button": HTMLButtonElement;
        "canvas": HTMLCanvasElement;
        "caption": HTMLTableCaptionElement;
        "cite": HTMLElement;
        "code": HTMLElement;
        "col": HTMLTableColElement;
        "colgroup": HTMLTableColElement;
        "data": HTMLDataElement;
        "datalist": HTMLDataListElement;
        "dd": HTMLElement;
        "del": HTMLModElement;
        "details": HTMLDetailsElement;
        "dfn": HTMLElement;
        "dialog": HTMLDialogElement;
        "dir": HTMLDirectoryElement;
        "div": HTMLDivElement;
        "dl": HTMLDListElement;
        "dt": HTMLElement;
        "em": HTMLElement;
        "embed": HTMLEmbedElement;
        "fieldset": HTMLFieldSetElement;
        "figcaption": HTMLElement;
        "figure": HTMLElement;
        "font": HTMLFontElement;
        "footer": HTMLElement;
        "form": HTMLFormElement;
        "frame": HTMLFrameElement;
        "frameset": HTMLFrameSetElement;
        "h1": HTMLHeadingElement;
        "h2": HTMLHeadingElement;
        "h3": HTMLHeadingElement;
        "h4": HTMLHeadingElement;
        "h5": HTMLHeadingElement;
        "h6": HTMLHeadingElement;
        "head": HTMLHeadElement;
        "header": HTMLElement;
        "hgroup": HTMLElement;
        "hr": HTMLHRElement;
        "html": HTMLHtmlElement;
        "i": HTMLElement;
        "iframe": HTMLIFrameElement;
        "img": HTMLImageElement;
        "input": HTMLInputElement;
        "ins": HTMLModElement;
        "kbd": HTMLElement;
        "label": HTMLLabelElement;
        "legend": HTMLLegendElement;
        "li": HTMLLIElement;
        "link": HTMLLinkElement;
        "main": HTMLElement;
        "map": HTMLMapElement;
        "mark": HTMLElement;
        "marquee": HTMLMarqueeElement;
        "menu": HTMLMenuElement;
        "meta": HTMLMetaElement;
        "meter": HTMLMeterElement;
        "nav": HTMLElement;
        "noscript": HTMLElement;
        "object": HTMLObjectElement;
        "ol": HTMLOListElement;
        "optgroup": HTMLOptGroupElement;
        "option": HTMLOptionElement;
        "output": HTMLOutputElement;
        "p": HTMLParagraphElement;
        "param": HTMLParamElement;
        "picture": HTMLPictureElement;
        "pre": HTMLPreElement;
        "progress": HTMLProgressElement;
        "q": HTMLQuoteElement;
        "rp": HTMLElement;
        "rt": HTMLElement;
        "ruby": HTMLElement;
        "s": HTMLElement;
        "samp": HTMLElement;
        "script": HTMLScriptElement;
        "section": HTMLElement;
        "select": HTMLSelectElement;
        "slot": HTMLSlotElement;
        "small": HTMLElement;
        "source": HTMLSourceElement;
        "span": HTMLSpanElement;
        "strong": HTMLElement;
        "style": HTMLStyleElement;
        "sub": HTMLElement;
        "summary": HTMLElement;
        "sup": HTMLElement;
        "table": HTMLTableElement;
        "tbody": HTMLTableSectionElement;
        "td": HTMLTableDataCellElement;
        "template": HTMLTemplateElement;
        "textarea": HTMLTextAreaElement;
        "tfoot": HTMLTableSectionElement;
        "th": HTMLTableHeaderCellElement;
        "thead": HTMLTableSectionElement;
        "time": HTMLTimeElement;
        "title": HTMLTitleElement;
        "tr": HTMLTableRowElement;
        "track": HTMLTrackElement;
        "u": HTMLElement;
        "ul": HTMLUListElement;
        "var": HTMLElement;
        "video": HTMLVideoElement;
        "wbr": HTMLElement;
}

3. Event 事件类型

3.1 Event类型介绍

Event接口表示一个DOM事件,包含了事件的基本信息,如事件类型、目标元素等。可以使用该接口来定义事件的类型
可以理解为Event类型是事件的基本类型,所有不同类型的event事件都是继承于Event类型。

简单写一个继承。例如:


    <template>
        <div @click="clickMyEvent">MyEvent</div>
    </template>
    
    interface MyEvent extends Event {
        mess: string
    }

    const clickMyEvent = (e: MouseEvent) => {
        // 这里的MyEvent就是继承自Event的类型。
        let targetMouseEvent: MyEvent = {
            mess: 'ok',
            ...e
        }  
    }

3.2 常见的事件类型

总的事件 typescript/lib/lib.dom.d.ts


    interface GlobalEventHandlersEventMap {
        "abort": UIEvent;
        "animationcancel": AnimationEvent;
        "animationend": AnimationEvent;
        "animationiteration": AnimationEvent;
        "animationstart": AnimationEvent;
        "auxclick": MouseEvent;
        "beforeinput": InputEvent;
        "blur": FocusEvent;
        "cancel": Event;
        "canplay": Event;
        "canplaythrough": Event;
        "change": Event;
        "click": MouseEvent;
        "close": Event;
        "compositionend": CompositionEvent;
        "compositionstart": CompositionEvent;
        "compositionupdate": CompositionEvent;
        "contextmenu": MouseEvent;
        "copy": ClipboardEvent;
        "cuechange": Event;
        "cut": ClipboardEvent;
        "dblclick": MouseEvent;
        "drag": DragEvent;
        "dragend": DragEvent;
        "dragenter": DragEvent;
        "dragleave": DragEvent;
        "dragover": DragEvent;
        "dragstart": DragEvent;
        "drop": DragEvent;
        "durationchange": Event;
        "emptied": Event;
        "ended": Event;
        "error": ErrorEvent;
        "focus": FocusEvent;
        "focusin": FocusEvent;
        "focusout": FocusEvent;
        "formdata": FormDataEvent;
        "gotpointercapture": PointerEvent;
        "input": Event;
        "invalid": Event;
        "keydown": KeyboardEvent;
        "keypress": KeyboardEvent;
        "keyup": KeyboardEvent;
        "load": Event;
        "loadeddata": Event;
        "loadedmetadata": Event;
        "loadstart": Event;
        "lostpointercapture": PointerEvent;
        "mousedown": MouseEvent;
        "mouseenter": MouseEvent;
        "mouseleave": MouseEvent;
        "mousemove": MouseEvent;
        "mouseout": MouseEvent;
        "mouseover": MouseEvent;
        "mouseup": MouseEvent;
        "paste": ClipboardEvent;
        "pause": Event;
        "play": Event;
        "playing": Event;
        "pointercancel": PointerEvent;
        "pointerdown": PointerEvent;
        "pointerenter": PointerEvent;
        "pointerleave": PointerEvent;
        "pointermove": PointerEvent;
        "pointerout": PointerEvent;
        "pointerover": PointerEvent;
        "pointerup": PointerEvent;
        "progress": ProgressEvent;
        "ratechange": Event;
        "reset": Event;
        "resize": UIEvent;
        "scroll": Event;
        "scrollend": Event;
        "securitypolicyviolation": SecurityPolicyViolationEvent;
        "seeked": Event;
        "seeking": Event;
        "select": Event;
        "selectionchange": Event;
        "selectstart": Event;
        "slotchange": Event;
        "stalled": Event;
        "submit": SubmitEvent;
        "suspend": Event;
        "timeupdate": Event;
        "toggle": Event;
        "touchcancel": TouchEvent;
        "touchend": TouchEvent;
        "touchmove": TouchEvent;
        "touchstart": TouchEvent;
        "transitioncancel": TransitionEvent;
        "transitionend": TransitionEvent;
        "transitionrun": TransitionEvent;
        "transitionstart": TransitionEvent;
        "volumechange": Event;
        "waiting": Event;
        "webkitanimationend": Event;
        "webkitanimationiteration": Event;
        "webkitanimationstart": Event;
        "webkittransitionend": Event;
        "wheel": WheelEvent;
    }

简单举个例子:


    <div @click="clickEvent"></div> 
    <div @change=changeEvent"></div> 
    <div @keyboard="KeyboardEvent" >Keyboard</div>
    
     const KeyboardEvent = (e: KeyboardEvent): void => {}
     const clickEvent = (e: MouseEvent): void => {}
     const changeEvent = (e: Event): void => {}

3.3 React中事件的类型

React中,事件类型是通过合成事件(SyntheticEvent)来定义的,并统一放在React.MouseEvent和React.KeyboardEvent等React的内置类型中的。


MouseEvent<T = Element> 鼠标事件对象
TouchEvent<T = Element> 触摸事件对象
ChangeEvent<T = Element> Change 事件对象
ClipboardEvent<T = Element> 剪贴板事件对象
DragEvent<T = Element> 拖拽事件对象
WheelEvent<T = Element> 滚轮事件对象
AnimationEvent<T = Element> 动画事件对象
TransitionEvent<T = Element> 过渡事件对象

为了兼容类型,建议最好多使用框架提供的类型声明


const startDrag = (e: React.MouseEvent<HTMLDivElement, MouseEvent>): void => {}
const onDragStart = (event: React.DragEvent<HTMLDivElement>: void => {}

posted @ 2024-04-18 17:59  sk-xm  阅读(383)  评论(0编辑  收藏  举报