前言
根據前面的介紹,我們知道根據是否繼承基本 HTML 元素,可以將自定義元素分為兩類“
- Autonomous custom elements 自主定製元素
- Customized built-in elements 自定義內建元素
由此產生了一個疑問:這兩者在使用上到底有何區別?
且讓我通過本篇文章試著解釋一下這個問題。
Autonomous custom elements
自主定製元素,是獨立的元素,它不繼承其他內建的 HTML 元素。
你可以直接把它們寫成HTML標籤的形式,來在頁面上使用。例如 <my-card>
,或者是document.createElement("my-card")
這樣。
示例
下面是一個建立和使用 Autonomous custom elements 的例子:
<!-- index.html -->
<body>
<my-card></my-card>
<script src="./index.js"></script>
</body>
// index.js
class MyCard extends HTMLElement {
constructor() {
super();
let shadow = this.attachShadow({ mode: "open" });
let containerEle = document.createElement("div");
containerEle.style.display = "flex";
containerEle.style.flexDirection = "column"
containerEle.style.margin = "100px";
containerEle.style.border = "1px solid #aaa";
const headerEle = document.createElement("div");
headerEle.innerText = "名片";
headerEle.style.height = "20px";
headerEle.style.padding = "10px";
headerEle.style.borderBottom = "1px solid blue";
const bodyEle = document.createElement("div");
bodyEle.innerText = "姓名:程式設計三昧";
bodyEle.style.padding = "10px";
containerEle.appendChild(headerEle);
containerEle.appendChild(bodyEle);
shadow.appendChild(containerEle);
}
}
customElements.define("my-card", MyCard);
其效果如下:
開啟開發者工具,檢視 DOM 結構,如下圖所示:
嘗試一
然後,我試著將註冊介面傳參改為 customElements.define("my-card", MyCard, {extends: "p"});
,結果,頁面不顯示,也無任何報錯資訊。
嘗試二
如果將 MyCard 類改為繼承自 HTMLDivElement,即:
// index.js
class MyCard extends HTMLDivElement{
constructor(){
super();
……
}
}
……
頁面有報錯:
嘗試三
在自定義元素的構造器的結束部分加入以下程式碼:
this.style.display = "block";
this.style.border = "2px solid #aaa";
邊框新增成功,這裡要注意的是:繼承自 HTMLElement 的樣式 display 置為 inline,如果不重新設定 display 的值,那麼樣式效果會顯示不出來。
Customized built-in elements
繼承自基本的HTML元素。在建立時,你必須指定所需擴充套件的元素,使用時,需要先寫出基本的元素標籤,並通過 is
屬性指定custom element的名稱。例如<p is="my-card">
, 或者 document.createElement("p", { is: "my-card" })
。
示例
下面是一個使用 Customized built-in elements 的例子:
<!--index.html-->
<body>
<div is="my-card"></div>
<script src="./index.js"></script>
</body>
// index.js
class MyCard extends HTMLDivElement {
constructor() {
super();
let shadow = this.attachShadow({ mode: "open" });
let containerEle = document.createElement("div");
containerEle.style.display = "flex";
containerEle.style.flexDirection = "column"
containerEle.style.margin = "100px";
containerEle.style.border = "1px solid #aaa";
const headerEle = document.createElement("div");
headerEle.innerText = "名片";
headerEle.style.height = "20px";
headerEle.style.padding = "10px";
headerEle.style.borderBottom = "1px solid blue";
const bodyEle = document.createElement("div");
bodyEle.innerText = "姓名:程式設計三昧";
bodyEle.style.padding = "10px";
containerEle.appendChild(headerEle);
containerEle.appendChild(bodyEle);
shadow.appendChild(containerEle);
}
}
customElements.define("my-card", MyCard, {extends: "div"});
效果跟 Autonomous custom elements 效果相同,其 DOM 結構如下:
嘗試一
如果在 index.html
中只使用 my-card
標籤,則沒有任何顯示。
嘗試二
如果將父類中的 HTMLDivElement 改為 HTMLElement,頁面有報錯:
嘗試三
如果去掉 customElements.define()
的第三個引數,則無報錯也無頁面顯示。
總結
綜合上述,可以總結如下:
- Autonomous custom elements 的建構函式只能繼承 HTMLElement,且呼叫
customElements.define()
方法時不需要第三個引數; - HTML 中直接使用 Autonomous custom elements 定義的標籤名稱即可;
- Autonomous custom elements 樣式的 display 值預設為 inline,如有需要,可重新設定;
- Customized built-in elements 的建構函式一般只能繼承可用的基本 HTML 標籤類,且呼叫
customElements.define()
方法時必須要傳入第三個引數,第三個引數一般為:{extends: "標籤名"}
; - HTML 中直接使用 Customized built-in elements 時,需要通過元件建構函式繼承類的基本標籤名 +
is="自定義標籤名"
。
~
~ 本文完,感謝閱讀!
~
學習有趣的知識,結識有趣的朋友,塑造有趣的靈魂!
本作品採用《CC 協議》,轉載必須註明作者和本文連結