你可以使用自訂元素,建構自己的 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;
    ...
  }
}