【RPU-A】HTML 增加 Form Participation API 支持
類別
周邊動態/Related Project Update
置信度
Announcement
起始時間
2019-01-08
內容
Web Components 作為官方的組件化方案,由於各種實際操作上的問題飽受詬病,其中一點就是無法自定義表單控制項,仍然只能靠 <input>
或者 <textarea>
元素來組建表單內容而無法自定義同類型的元素(除非不依賴 form 自有的 submit 實現)。
新的 Form Participation API 為自定義表單控制項元素提供了可能性,該提案引入了兩套 API:
- Event-based participation
- Form-associated Custom Element
前者已經進入 HTML 規範,而後者仍然處在 Review 階段中,預計能在不遠的將來合併。
對於 Event-based participation 的方式,<form>
在提交階段會觸發 formdata 事件,其事件對象的 formData 屬性即為當前的 FormData。在該事件的處理函數中,可以對其進行修改,從而改變表單的提交內容。形如:
class ShoppingCartApp {
constructor() {
document.querySelector(#cart-form).addEventListener(formdata, this.onFormData.bind(this))
// or el.onformdata = ...
}
onFormData(event) {
event.formData.append(customer-id, this.customerId)
event.formData.append(affiliate-code, this.affiliateCode)
}
}
}
雖然能夠擴充欄位,但 Event-based participation 並沒有將該組件標記為表單控制項,而是一個通用的預處理過程,所以也能夠用於添加欄位以外的其它操作,但一般只用於簡單場景。
而另一種方案 Form-associated Custom Element 會確實將某個 Custom Element 標記為表單控制項,通過名為 formAssociated
的靜態屬性。而後能夠在構造函數中訪問繼承到的 attachInternals() 方法:
class MyControl extends HTMLElement {
static get formAssociated() { return true; }
constructor() {
super();
this.internals = this.attachInternals()
}
}
attachInternals 的返回值是一個 ElementInternals 對象,其結構如下:
interface ElementInternals {
setFormValue(value: FormDataEntryValue, entrySource?: FormData): void
readonly form?: HTMLFormElement
setValidity(flags: ValidityStateFlags, message?: string): void
readonly willValidate: boolean
readonly validity: ValidityState
readonly validationMessage: string
checkValidity(): boolean
reportValidity(): boolean
readonly labels: NodeList
}
該對象用於獲取表單狀態以及進行表單操作。除此之外,標記為 formAssociated 的元素還將獲得額外的生命周期:
- formAssociatedCallback(form?: HTMLFormElement):與 <form> 關聯後調用;
- disabledStateChangedCallback(disabled: boolean):所在 <fieldset> 啟用狀態變化時調用;
- formResetCallback():表單重置時調用;
- restoreValueCallback(v: FormDataEntryValue, mode: restore | autocomplete):非用戶填充時調用;
而後通過 ElementInternals 中的內容以及相應的生命周期與表單進行實時交互。
相關鏈接
- Form Participation API 的 Explainer:https://docs.google.com/document/d/1JO8puctCSpW-ZYGU8lF-h4FWRIDQNDVexzHoOQ2iQmY/edit#
- Event-based form participation API 的 PR:Event-based form participation by tkent-google · Pull Request #4239 · whatwg/html
- Form-associated Custom Element API 的 PR:Custom elements: Add element.attachInternals() and ElementInternals interface by tkent-google · Pull Request #4324 · whatwg/html
- Web Components 中的相關討論:Need callback for form submit data · Issue #187 · w3c/webcomponents
- Design Review 的 issue:Form Participation API · Issue #305 · w3ctag/design-reviews
推薦閱讀: