你可以使用自訂元素,建構自己的 HTML 標記。這份檢查清單涵蓋了建構高品質元素的最佳做法。
自訂元素可讓您擴充 HTML 及定義自己的標記。他們是
功能非常強大,但是等級很低
請務必明確指出導入自己的元素最佳方式
為了協助您創造最佳體驗,我們整理了以下內容
檢查清單。它會詳細列出我們認為
自訂元素的行為良好。
檢查清單
陰影 DOM
建立用於封裝樣式的陰影根。
為什麼?
在元素的陰影根目錄中封裝樣式,確保樣式可正常運作
以及無論在何處使用如果開發人員
想將元素放置在另一個元素的陰影根目錄中這個
則會套用到核取方塊或圓形按鈕等簡單元素有可能
影子根層級唯一的內容會成為
所發出的呼叫頻率
範例
<howto-checkbox>
元素。
在建構函式中建立陰影根。
為什麼?
建構函式是指您具備元素的專屬知識 。
建議您盡快設定您不希望其他導入項目的詳細設定
元素之間的關聯在稍後的回呼中執行這項操作,例如
connectedCallback
意味著您必須面對
因此系統無法將元素卸離,然後再重新附加至文件中。
範例
<howto-checkbox>
元素。
將元素建立的任何子項放入其陰影根目錄中。
為什麼?
由元素建立的子項是其實作的一部分,且應
私人。如果沒有影子根防護機制,JavaScript 以外的位置
無意間幹擾兒童
範例
<howto-tabs>
元素。
使用 <slot>將 Light DOM 子項投影到 shadow DOM 中
為什麼?
允許元件使用者指定元件中的內容,因為 HTML 子項可讓元件變得更加可組合項。如果瀏覽器不支援自訂元素,巢狀內容仍可繼續供使用者存取、顯示和存取。
範例
<howto-tabs>
元素。
設定 :host
顯示樣式 (例如 block
、
inline-block
、flex
),除非您偏好使用預設值
inline
。
為什麼?
自訂元素預設為 display: inline
,因此將自訂元素設為
width
或 height
不會有任何作用。這經常
是開發人員感到驚訝的現象,且可能導致
版面配置除非你偏好 inline
螢幕,否則你可以
一律設定預設的 display
值。
範例
<howto-checkbox>
元素。
加入符合隱藏屬性的 :host
顯示樣式。
為什麼?
採用預設 display
樣式的自訂元素,例如
:host { display: block }
將覆寫指定值
內建
hidden
屬性 。
如果您預期將 hidden
設為
屬性,即可算繪 display: none
。此外,
預設的 display
樣式,新增 hidden
的支援
搭配 :host([hidden]) { display: none }
。
範例
<howto-checkbox>
元素。
屬性和屬性
不覆寫作者設定的全域屬性。
為什麼?
全域屬性是指所有 HTML 元素中顯示的屬性,只有部分通知
範例包括 tabindex
和 role
。自訂元素
建議將初始 tabindex
設為 0,使其成為鍵盤
可聚焦。不過,您應該事先檢查開發人員是否使用
元素已將這個參數設為其他值。舉例來說,假設
tabindex
到 -1,表示他們不想
才能進行互動
範例
<howto-checkbox>
元素。詳細說明請參閱
不要覆寫網頁作者,
一律接受基本資料 (字串、數字、布林值) 做為任一屬性
或屬性。
為什麼?
自訂元素 (例如內建對應元素) 應可供設定。
設定能以宣告方式、透過屬性傳遞,或以命令方式傳遞
透過 JavaScript 屬性在理想情況下,每項屬性都應該連結至
和對應的屬性
範例
<howto-checkbox>
元素。
盡量將原始資料屬性和屬性保持同步,反映
屬性,反之亦然。
為什麼?
您永遠不會知道使用者如何與您的元素互動。例如:
在 JavaScript 中設定屬性,然後預期讀取該值
透過 getAttribute()
等 API如果每項屬性都有
資源與資源相對應
使用者與元素搭配運作也就是呼叫
setAttribute('foo', value)
也應設定對應的
foo
屬性,反之亦然。當然,
此規則。請勿反映頻率高的屬性,例如:
currentTime
。請善用判斷力。如果是
似乎會與資源或屬性互動
沒辦法反映這一點
範例
<howto-checkbox>
元素。詳細說明請參閱
避免重複性問題 。
請僅接受多媒體資料 (物件、陣列) 做為屬性。
為什麼?
一般來說,不會包含一些內建 HTML 元素的內建範例。
透過其接受豐富的資料 (純文字 JavaScript 物件和陣列)
屬性。是透過方法呼叫或
資源。接受多媒體資料擁有幾項明顯的缺點
屬性:將大型物件序列化為字串可能非常昂貴。
所有物件參照都會在這項字串化程序中遺失。適用對象
例如,如果您將一個物件對應至另一個物件的參照,
或 DOM 節點,這些參照就會遺失
請勿將豐富的資料屬性反映至屬性。
為什麼?
將豐富的資料屬性反映到屬性不需花太多錢。
需要對相同的 JavaScript 物件進行序列化與取消序列化作業。除非
您的用途只能透過這項功能解決
務必避免。
建議檢查在元素之前已設定的屬性
已升級
為什麼?
使用你的元素的開發人員可能會嘗試在元素上設定屬性
載入其定義之前。如果
開發人員使用的是可處理載入元件的架構,
並將屬性繫結至模型。
範例
<howto-checkbox>
元素。詳細說明請見
將屬性設為延遲 。
請勿自行套用類別。
為什麼?
需要表示狀態的元素應使用屬性來表示。
class
屬性通常視為
並自行撰寫文字
開發人員類別簡介
活動
分派事件以回應內部元件活動。
為什麼?
您的元件可能有屬性變更,以因應
只有元件知道的知識,例如計時器或動畫
或是資源完成載入有助於調度事件
回應這些變更,並通知主機元件的狀態
也不一樣
不要為回應主機設定屬性 (向下) 分派事件
資料流)。
為什麼?
分派事件以回應主機設定時,作業方式不流暢
(由於主機剛設定,主機就知道目前狀態)。分派事件
回應主機設定,可能會導致資料發生無限迴圈
繫結系統
範例
<howto-checkbox>
元素。
釋疑影片
不要覆寫網頁作者
使用元素的開發人員可能會想覆寫某些值
這項動作會抹除機器的記憶體內容
並將虛擬機器重設為初始狀態例如,將 ARIA role
變更為可聚焦性
tabindex
。請確認是否已設定這些和任何其他全域屬性。
才能套用自己的值
connectedCallback () {
if ( ! this . hasAttribute ( 'role '))
this . setAttribute ( 'role ', 'checkbox ');
if ( ! this . hasAttribute ( 'tabindex '))
this . setAttribute ( 'tabindex ', 0 );
將屬性設為延遲
在元素開始前,開發人員可能會嘗試先設定元素的屬性
定義已載入如果開發人員使用
以及處理載入元件、將元件插入頁面
將屬性與模型繫結至模型中
在下方範例中,Angular 會以宣告方式繫結模型的
設為核取方塊 checked
屬性的 isChecked
屬性。如果
How to-checkbox 會延遲載入,很有可能讓 Angular 嘗試
在元素升級前勾選的屬性。
<howto-checkbox [checked]="defaults.isChecked"></howto-checkbox>
自訂元素應檢查是否有任何屬性
您可能已經在執行個體中設定<howto-checkbox>
我們用名為 _upgradeProperty()
的方法示範這個模式
connectedCallback () {
...
this . _upgradeProperty ( 'checked ');
}
_upgradeProperty ( prop ) {
if ( this . hasOwnProperty ( prop )) {
let value = this [ prop ];
delete this [ prop ];
this [ prop ] = value ;
}
}
_upgradeProperty()
會從未升級的執行個體中擷取值並刪除
屬性,這樣就不會覆蓋自訂元素本身的屬性 setter。
這樣一來,元素定義最終完全載入後,就能立即
反映正確的狀態
避免重複發生問題
您可能會很想使用 attributeChangedCallback()
將狀態反映為
基礎屬性,例如:
// When the [checked] attribute changes, set the checked property to match.
attributeChangedCallback ( name , oldValue , newValue ) {
if ( name === 'checked ')
this . checked = newValue ;
}
不過,如果屬性 setter 也反映
屬性。
set checked ( value ) {
const isChecked = Boolean ( value );
if ( isChecked )
// OOPS! This will cause an infinite loop because it triggers the
// attributeChangedCallback() which then sets this property again.
this . setAttribute ( 'checked ', '');
else
this . removeAttribute ( 'checked ');
}
另一種方式是允許屬性 setter 反映屬性
getter 可以根據屬性決定其值。
set checked ( value ) {
const isChecked = Boolean ( value );
if ( isChecked )
this . setAttribute ( 'checked ', '');
else
this . removeAttribute ( 'checked ');
}
get checked () {
return this . hasAttribute ( 'checked ');
}
在此範例中,新增或移除屬性也會設定屬性。
最後,attributeChangedCallback()
可用來處理連帶效果
例如套用 ARIA 狀態
attributeChangedCallback ( name , oldValue , newValue ) {
const hasValue = newValue !== null ;
switch ( name ) {
case 'checked ':
// Note the attributeChangedCallback is only handling the *side effects*
// of setting the attribute.
this . setAttribute ( 'aria - checked ', hasValue );
break ;
...
}
}