這項技術仍是比較容易理解的;顧名思義,自定義標籤就是 HTML
元素,好比 <div>
、<section>
或 <article>
, 可是咱們能夠經過瀏覽器 API 本身命名。自定義元素就像那些標準的 HTML 元素同樣(名字在尖括號中) ,只不過它們老是有一個破折號,好比 <news-slider>
或 <bacon-cheeseburger >
。這麼作的目的是爲了防止與原生內置標籤產生衝突。javascript
自定義元素包含本身的語義、行爲、標記,能夠在框架和瀏覽器之間共享。css
class MyComponent extends HTMLElement {
connectedCallback() {
this.innerHTML = `<h1>Hello world</h1>`
}
}
customElements.define('my-component', MyComponent)
複製代碼
在這個例子中,咱們定義了咱們本身的 HTML 元素 <my-component>
。誠然,它並無作不少工做,但這是定製元素的基本構建塊。全部自定義元素都必須以某種方式擴展 HTMLElement
,才能在瀏覽器中註冊並使用。html
在編碼中,沒有依賴任何第三方框架,瀏覽器廠商在升級時,也在致力於規範的向下兼容,幾乎保證了按照規範編寫的組件不會受到破壞API變化的影響。更重要的是,這些組件一般能夠用於當今最流行的框架,包括 Angular、 React、 Vue 和其餘框架。更多java
Shadow DOM
是 DOM
的封裝版本。這使得開發者能夠有效地將 DOM
片斷彼此隔離開來,包括任何能夠用做 CSS
選擇器的內容以及與它們相關的樣式。一般,文檔做用域內的任何內容都稱爲 light DOM
,而Shadow Root
中的任何內容都稱爲Shadow DOM
。api
當使用 light DOM
時,可使用 document.querySelector('selector')
選擇元素,或者使用 element.querySelector('selector')
選擇任何元素的子元素;瀏覽器
一樣,能夠經過調用 shadowRoot.querySelector
來選擇陰影根的子元素,而 shadowRoot
是對文檔片斷的引用; 區別在於陰影根的子元素不能從 light DOM
中選擇。例如,若是咱們有一個包含 <button>
的陰影根,調用 shadowRoot.querySelector('button')
將返回咱們的按鈕,可是不能document's
查詢選擇器獲取該元素,由於它屬於不一樣的 DocumentOrShadowRoot
實例。markdown
在這方面,shadow DOM
的工做方式有點像 <iframe>
,其中shadow DOM
中的內容與document
的其他部分隔離開來; 然而,當咱們建立 shadow root
時,咱們仍然能夠徹底控制頁面的這一部分,可是範圍僅限於上下文。這就是咱們所說的封裝。app
若是您曾經編寫太重用相同 id 的組件,或者依賴於 CSS-in-JS 工具或 CSS 命名策略(好比 BEM) ,那麼 shadow DOM 有可能改善您的開發人員體驗。框架
想象一下這樣的場景:ide
<div>
<div id="example">
<!-- Pseudo-code used to designate a shadow root -->
<#shadow-root>
<style> button { background: tomato; color: white; } </style>
<button id="button">This will use the CSS background tomato</button>
</#shadow-root>
</div>
<button id="button">Not tomato</button>
</div>
複製代碼
除了 <#shadow-root>
的僞代碼(這裏使用它來劃分 shadow DOM
的邊界)以外,其餘的 HTML
是徹底有效的。爲了在上面的節點上附加一個shadow root
,咱們能夠運行下面的代碼:
const shadowRoot = document.getElementById('example').attachShadow({ mode: 'open' })
shadowRoot.innerHTML = `<style> button { color: tomato; } </style> <button id="button"> This will use the CSS color tomato <slot></slot> </button>`
複製代碼
經過使用 <slot>
元素,影子根還能夠包含其餘外部節點內容。使用插槽會將用戶內容從外部節點 放到陰影根元素的指定位置。
命名恰當的 HTML <template>
元素容許咱們在普通 HTML
流中重用的代碼模板,這些模板不會當即顯示,但能夠在須要的時候使用。
<template id="book-template">
<li><span class="title"></span> — <span class="author"></span></li>
</template>
<ul id="books"></ul>
複製代碼
上面的例子不會渲染任何內容,直到腳本使用了模板,實例化了代碼並告訴瀏覽器該如何處理它。
const fragment = document.getElementById('book-template')
const books = [
{ title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' },
{ title: 'A Farewell to Arms', author: 'Ernest Hemingway' },
{ title: 'Catch 22', author: 'Joseph Heller' },
]
books.forEach((book) => {
// Create an instance of the template content
const instance = document.importNode(fragment.content, true)
// Add relevant content to the template
instance.querySelector('.title').innerHTML = book.title
instance.querySelector('.author').innerHTML = book.author
// Append the instance ot the DOM
document.getElementById('books').appendChild(instance)
})
複製代碼
表面上,使用利用模板 API 的服務的用戶能夠編寫任何形狀或結構的模板,這些模板能夠在之後建立。網站上的另外一個頁面可能使用相同的服務,可是模板的結構是這樣的:
<template id="book-template">
<li><span class="author"></span>'s classic novel <span class="title"></span></li>
</template>
<ul id="books"></ul>
複製代碼
Web Components 規範是一組底層 api,它們將隨着開發人員的需求而不斷髮展和演進。
在下一篇文章中,咱們將更深刻地瞭解 HTML 模板部分。而後,咱們將繼續討論自定義元素和影子 DOM。最後,咱們將着眼於更高層次的工具,並將其與當今流行的庫和框架結合起來,從而總結所有內容。