前端開(kāi)發(fā)typescript中常用的dom元素類型
在 TypeScript 中處理 DOM 操作時(shí),有一整套完善的類型系統(tǒng)。下面我將系統(tǒng)地整理前端開(kāi)發(fā)中最常用的 DOM 元素類型。
基礎(chǔ) DOM 類型體系
1. 頂層類型
// 所有 DOM 節(jié)點(diǎn)的基類
let node: Node = document.createElement('div')
// 所有 HTML 元素的基類
let element: Element = document.querySelector('div')!
// 所有具體的 HTML 元素都繼承自 HTMLElement
let htmlElement: HTMLElement = document.createElement('div')
// 文檔對(duì)象
let doc: Document = document
// 窗口對(duì)象
let win: Window = window
常用具體元素類型
1. 輸入控件類
// 輸入框
let input: HTMLInputElement = document.createElement('input')
input.value = 'hello'
input.checked = true
input.type = 'password'
input.placeholder = '請(qǐng)輸入'
input.files // FileList | null
// 文本域
let textarea: HTMLTextAreaElement = document.createElement('textarea')
textarea.value = '多行文本'
textarea.rows = 5
textarea.cols = 30
// 按鈕
let button: HTMLButtonElement = document.createElement('button')
button.disabled = true
button.type = 'submit'
// 選擇框
let select: HTMLSelectElement = document.createElement('select')
let option: HTMLOptionElement = document.createElement('option')
select.value = 'option1'
select.selectedIndex = 0
select.options // HTMLOptionsCollection
2. 容器和布局類
// 通用塊級(jí)容器
let div: HTMLDivElement = document.createElement('div')
let span: HTMLSpanElement = document.createElement('span')
let section: HTMLElement = document.createElement('section') // 直接用 HTMLElement
let article: HTMLElement = document.createElement('article')
// 列表
let ul: HTMLUListElement = document.createElement('ul')
let ol: HTMLOListElement = document.createElement('ol')
let li: HTMLLIElement = document.createElement('li')
// 表格相關(guān)
let table: HTMLTableElement = document.createElement('table')
let tr: HTMLTableRowElement = document.createElement('tr')
let td: HTMLTableCellElement = document.createElement('td')
let th: HTMLTableCellElement = document.createElement('th')
let tbody: HTMLTableSectionElement = document.createElement('tbody')
let thead: HTMLTableSectionElement = document.createElement('thead')
// 表單
let form: HTMLFormElement = document.createElement('form')
form.action = '/submit'
form.method = 'POST'
form.elements // HTMLFormControlsCollection
3. 媒體類
// 圖片
let img: HTMLImageElement = document.createElement('img')
img.src = '/image.jpg'
img.alt = '描述'
img.width = 100
img.height = 100
img.complete // 圖片是否加載完成
// 音頻
let audio: HTMLAudioElement = document.createElement('audio')
audio.src = '/audio.mp3'
audio.volume = 0.5
audio.play()
audio.pause()
// 視頻
let video: HTMLVideoElement = document.createElement('video')
video.src = '/video.mp4'
video.poster = '/poster.jpg'
video.width = 640
video.height = 360
video.playbackRate = 1.5
// 畫布
let canvas: HTMLCanvasElement = document.createElement('canvas')
let ctx: CanvasRenderingContext2D | null = canvas.getContext('2d')
4. 鏈接和元數(shù)據(jù)類
// 鏈接
let a: HTMLAnchorElement = document.createElement('a')
a.
a.target = '_blank'
a.download = 'file.pdf'
// 圖片鏈接
let area: HTMLAreaElement = document.createElement('area')
area.shape = 'rect'
area.coords = '0,0,100,100'
// Meta 信息
let meta: HTMLMetaElement = document.createElement('meta')
meta.name = 'description'
meta.content = '頁(yè)面描述'
// 鏈接資源
let link: HTMLLinkElement = document.createElement('link')
link.rel = 'stylesheet'
link.href = '/style.css'
特定功能的元素類型
1. 進(jìn)度和度量
// 進(jìn)度條
let progress: HTMLProgressElement = document.createElement('progress')
progress.value = 50
progress.max = 100
// 度量
let meter: HTMLMeterElement = document.createElement('meter')
meter.value = 0.6
meter.min = 0
meter.max = 1
meter.low = 0.3
meter.high = 0.8
meter.optimum = 0.5
2. 嵌入內(nèi)容
// iframe
let iframe: HTMLIFrameElement = document.createElement('iframe')
iframe.src = '/other-page.html'
iframe.contentWindow // Window | null
iframe.contentDocument // Document | null
// 嵌入對(duì)象
let object: HTMLObjectElement = document.createElement('object')
object.data = '/file.pdf'
object.type = 'application/pdf'
// 嵌入腳本
let script: HTMLScriptElement = document.createElement('script')
script.src = '/main.js'
script.async = true
script.defer = true
3. 表單中特有元素
// 單選/復(fù)選
let radio: HTMLInputElement = document.createElement('input')
radio.type = 'radio'
radio.name = 'gender'
radio.value = 'male'
radio.checked = true
let checkbox: HTMLInputElement = document.createElement('input')
checkbox.type = 'checkbox'
checkbox.checked = true
checkbox.indeterminate = false
// 文件上傳
let fileInput: HTMLInputElement = document.createElement('input')
fileInput.type = 'file'
fileInput.multiple = true
fileInput.accept = 'image/*'
// 隱藏輸入
let hidden: HTMLInputElement = document.createElement('input')
hidden.type = 'hidden'
hidden.value = 'secret-data'
// 顏色選擇器
let color: HTMLInputElement = document.createElement('input')
color.type = 'color'
color.value = '#ff0000'
// 范圍滑塊
let range: HTMLInputElement = document.createElement('input')
range.type = 'range'
range.min = 0
range.max = 100
range.step = 5
range.value = '50'
類型查詢和斷言
1. 獲取 DOM 元素
// 類型斷言
const canvas = document.getElementById('canvas') as HTMLCanvasElement
const input = <HTMLInputElement>document.querySelector('input[type="text"]')
// 安全的類型檢查
function isInputElement(el: HTMLElement): el is HTMLInputElement {
return el.tagName === 'INPUT'
}
// 使用實(shí)例
const element = document.getElementById('myElement')
if (element instanceof HTMLInputElement) {
element.value // TypeScript 知道這是 input
} else if (element instanceof HTMLTextAreaElement) {
element.value // 這也是 input 類型
}
// 更好的方式:使用類型守衛(wèi)
function getInput(id: string): HTMLInputElement | null {
const el = document.getElementById(id)
return el instanceof HTMLInputElement ? el : null
}
2. 集合類型
// NodeList
const nodes: NodeListOf<HTMLElement> = document.querySelectorAll('.item')
nodes.forEach(node => node.style.color = 'red')
// HTMLCollection
const forms: HTMLCollectionOf<HTMLFormElement> = document.forms
const images: HTMLCollectionOf<HTMLImageElement> = document.images
// 特定類型的集合
const allInputs = document.querySelectorAll<HTMLInputElement>('input')
// allInputs 的類型是 NodeListOf<HTMLInputElement>
// 類型化的集合
interface MyElements {
'username': HTMLInputElement
'submitBtn': HTMLButtonElement
'avatar': HTMLImageElement
}
function getElement<K extends keyof MyElements>(id: K): MyElements[K] | null {
return document.getElementById(id) as MyElements[K] | null
}
事件對(duì)象類型
1. 常見(jiàn)事件類型
// 鼠標(biāo)事件
function handleMouse(e: MouseEvent) {
e.clientX, e.clientY // 鼠標(biāo)坐標(biāo)
e.button // 按下的鼠標(biāo)鍵
e.ctrlKey, e.shiftKey // 修飾鍵
}
// 鍵盤事件
function handleKey(e: KeyboardEvent) {
e.key // 按下的鍵值
e.code // 物理按鍵代碼
e.altKey // 是否按下 Alt
e.repeat // 是否長(zhǎng)按重復(fù)
}
// 焦點(diǎn)事件
function handleFocus(e: FocusEvent) {
e.relatedTarget // 上一個(gè)/下一個(gè)焦點(diǎn)元素
}
// 表單事件
function handleSubmit(e: Event) {
e.preventDefault()
const form = e.target as HTMLFormElement
}
// 拖拽事件
function handleDrag(e: DragEvent) {
e.dataTransfer?.setData('text/plain', 'data')
}
// 剪貼板事件
function handlePaste(e: ClipboardEvent) {
const text = e.clipboardData?.getData('text/plain')
}
2. Vue 3 中的事件類型
<script setup lang="ts">
// 原生 DOM 事件
const handleClick = (e: MouseEvent) => {
console.log(e.clientX)
}
// Input 事件
const handleInput = (e: Event) => {
const target = e.target as HTMLInputElement
console.log(target.value)
}
// Change 事件
const handleChange = (e: Event) => {
const target = e.target as HTMLSelectElement
console.log(target.value)
}
// 鍵盤事件
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Enter') {
console.log('回車鍵按下')
}
}
// 自定義組件事件
interface Emits {
(e: 'update', value: string): void
(e: 'close', reason: 'click' | 'esc'): void
}
const emit = defineEmits<Emits>()
</script>
<template>
<input @click="handleClick">
<input @input="handleInput">
<select @change="handleChange">
<option value="1">選項(xiàng)1</option>
</select>
<input @keydown="handleKeyDown">
</template>
實(shí)用工具類型
1. 內(nèi)置的 DOM 工具類型
// 獲取元素屬性的類型
type InputValue = HTMLInputElement['value'] // string
type ButtonType = HTMLButtonElement['type'] // 'button' | 'submit' | 'reset'
type ElementTag = HTMLElement['tagName'] // string
// Partial 應(yīng)用于 DOM 配置
interface CanvasConfig {
width: number
height: number
context: CanvasRenderingContext2D
}
const config: Partial<CanvasConfig> = { width: 800 }
// 只讀 DOM 引用
const readonlyElement: Readonly<HTMLElement> = document.body
// readonlyElement.innerHTML = '' // ? 錯(cuò)誤
2. 自定義 DOM 類型
// 自定義數(shù)據(jù)屬性
interface DatasetMap {
userId: string
role: 'admin' | 'user'
theme: 'light' | 'dark'
}
function setDataset<T extends HTMLElement>(
el: T,
data: Partial<{ [K in keyof DatasetMap]: string }>
) {
Object.entries(data).forEach(([key, value]) => {
el.dataset[key] = value
})
}
const div = document.createElement('div')
setDataset(div, { userId: '123', role: 'admin' })
// div.dataset.userId 有類型提示
// 帶狀態(tài)的自定義元素
interface StatefulElement<T> extends HTMLElement {
state: T
setState: (newState: Partial<T>) => void
}
interface ButtonState {
loading: boolean
count: number
}
const btn = document.createElement('button') as StatefulElement<ButtonState>
btn.state = { loading: false, count: 0 }
btn.setState({ loading: true })
實(shí)際開(kāi)發(fā)模式
1. 工廠函數(shù)模式
// 類型安全的元素創(chuàng)建
function createElement<K extends keyof HTMLElementTagNameMap>(
tagName: K,
props?: Partial<HTMLElementTagNameMap[K]>
): HTMLElementTagNameMap[K] {
const el = document.createElement(tagName)
if (props) {
Object.assign(el, props)
}
return el
}
// 使用示例
const button = createElement('button', {
textContent: '點(diǎn)擊',
disabled: false,
className: 'btn-primary'
})
const input = createElement('input', {
type: 'email',
placeholder: '輸入郵箱',
value: ''
})
2. 類型守衛(wèi)工具
// DOM 類型守衛(wèi)集合
const domGuards = {
isInput: (el: Element | null): el is HTMLInputElement =>
el?.tagName === 'INPUT',
isButton: (el: Element | null): el is HTMLButtonElement =>
el?.tagName === 'BUTTON',
isSelect: (el: Element | null): el is HTMLSelectElement =>
el?.tagName === 'SELECT',
isTextArea: (el: Element | null): el is HTMLTextAreaElement =>
el?.tagName === 'TEXTAREA',
isForm: (el: Element | null): el is HTMLFormElement =>
el?.tagName === 'FORM'
}
// 使用
const element = document.getElementById('myInput')
if (domGuards.isInput(element)) {
element.value = '類型安全'
}
3. Vue 3 中的 DOM 模板引用
<script setup lang="ts">
import { ref, onMounted } from 'vue'
// 基本元素引用
const inputRef = ref<HTMLInputElement | null>(null)
const divRef = ref<HTMLDivElement | null>(null)
const canvasRef = ref<HTMLCanvasElement | null>(null)
// 多個(gè)元素引用
const itemRefs = ref<HTMLElement[]>([])
// 組件引用
import Modal from './Modal.vue'
const modalRef = ref<InstanceType<typeof Modal> | null>(null)
onMounted(() => {
// 類型安全的方法調(diào)用
inputRef.value?.focus()
canvasRef.value?.getContext('2d')
modalRef.value?.open()
})
</script>
<template>
<input ref="inputRef" type="text">
<div ref="divRef" class="container"></div>
<canvas ref="canvasRef"></canvas>
<!-- 多個(gè)元素 -->
<div
v-for="item in 5"
:ref="el => itemRefs.push(el as HTMLElement)"
:key="item"
>
Item {{ item }}
</div>
<Modal ref="modalRef" />
</template>
類型層次結(jié)構(gòu)
EventTarget (所有事件目標(biāo)的基類)
├── Node (所有 DOM 節(jié)點(diǎn)的基類)
│ ├── Element (所有元素的基類)
│ │ ├── HTMLElement (HTML 元素的基類)
│ │ │ ├── HTMLInputElement
│ │ │ ├── HTMLButtonElement
│ │ │ ├── HTMLDivElement
│ │ │ └── ...
│ │ └── SVGElement (SVG 元素)
│ ├── Text (文本節(jié)點(diǎn))
│ └── Comment (注釋節(jié)點(diǎn))
├── Window (窗口對(duì)象)
└── Document (文檔對(duì)象)
掌握這些 DOM 類型,可以讓你在處理瀏覽器 API 時(shí)獲得完整的類型支持和智能提示,減少運(yùn)行時(shí)錯(cuò)誤。
總結(jié)
到此這篇關(guān)于前端開(kāi)發(fā)typescript中常用dom元素類型的文章就介紹到這了,更多相關(guān)ts常用dom元素類型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript中的偽數(shù)組用法及說(shuō)明
這篇文章主要介紹了JavaScript中的偽數(shù)組用法及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
JavaScript結(jié)合canva實(shí)現(xiàn)簡(jiǎn)單的繪圖工具
這篇文章主要給大家介紹了如何使用JavaScript和HTML的Canvas標(biāo)簽創(chuàng)建一個(gè)簡(jiǎn)單的圖表工具,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-12-12
JavaScript獲取ul中l(wèi)i個(gè)數(shù)的方法
這篇文章主要介紹了JavaScript獲取ul中l(wèi)i個(gè)數(shù)的方法,涉及javascript針對(duì)頁(yè)面HTML元素的獲取及屬性操作相關(guān)技巧,需要的朋友可以參考下2017-02-02
如何從零開(kāi)始利用js手寫一個(gè)Promise庫(kù)詳解
ES2015 推出了JS 的 Promise ,而在沒(méi)有原生支持的時(shí)候,我們也可以使用諸如 Promises/A+ 的庫(kù)的幫助,在我們的代碼里實(shí)現(xiàn)Promise 的支持,下面這篇文章主要給大家介紹了如何從零開(kāi)始利用js手寫一個(gè)Promise庫(kù)的相關(guān)資料,需要的朋友可以參考下。2018-04-04
JS判斷頁(yè)面是否出現(xiàn)滾動(dòng)條的方法
這篇文章主要介紹了JS判斷頁(yè)面是否出現(xiàn)滾動(dòng)條的方法,涉及javascript針對(duì)頁(yè)面元素的讀取與判定實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07
在JavaScript中使用揭示模式創(chuàng)建對(duì)象的示例
揭示模式是一種在JavaScript中創(chuàng)建對(duì)象的方法,通過(guò)返回一個(gè)包含公開(kāi)屬性和方法的對(duì)象,可以控制哪些部分可以被外部訪問(wèn),從而實(shí)現(xiàn)更好的封裝和安全性,感興趣的朋友一起看看吧2024-12-12

