摘要:通過創(chuàng)建元素時也有不同也可以直接調(diào)用構(gòu)造函數(shù)創(chuàng)建注直到版本,擴展內(nèi)置元素依然在開發(fā)中。自定義元素被移入新的時調(diào)用。
很早我們就可以在 HTML 文檔中寫
通過瀏覽器提供的 Custom elements api 我們能定義一個自定義元素,并且告知 HTML 解析器如何正確地構(gòu)造一個元素,以及在該元素的屬性變化時執(zhí)行相應的處理。
定義新元素比如我們想要像
首先我們定義一個類 DateString 派生自 HTMLElement。
class DateString extends HTMLElement { constructor() { super() return } // 返回需要監(jiān)聽的屬性,當屬性值改變的時候會調(diào)用 attributeChangedCallback 這個方法 static get observedAttributes () { return ["ln"] } attributeChangedCallback (name, oldValue, newValue) { this.updateRendering (newValue) } // 元素插入到文檔中時調(diào)用 connectedCallback() { const ln = this.getAttribute("ln") this.updateRendering(ln) } // 元素從文檔中移除時調(diào)用 disconnectedCallback () { window.clearInterval(this.interval) } updateRendering (ln = "zh") { // 一個比較好的實踐就是在渲染時,檢查元素的 ownerDocument.defaultView, 如果不存在則什么都不干 if (!this.ownerDocument.defaultView) { return } if (this.interval) { window.clearInterval(this.interval) } this.interval = setInterval(() => { if (ln === "zh") { this.innerHTML = new Date().toLocaleString() } else { this.innerHTML = new Date().toString() } }, 1000) } }
然后調(diào)用 customElements.define() 注冊這個自定義元素,設置屬性并插入到 body 中。
customElements.define("date-string", DateString) const dateStr = document.createElement("date-string") dateStr.setAttribute("ln", "zh") document.body.appendChild(dateStr)
也可以用直接調(diào)用構(gòu)造函數(shù)創(chuàng)建元素
const dateStr = new DateString() dateStr.setAttribute("ln", "zh") document.body.appendChild(dateStr)
自定義元素可以使用符合規(guī)范的任意屬性名,下面說的派生內(nèi)置元素類型要自定義屬性,則要用 data-*
上面代碼那樣設置屬性很繁瑣,我們可以做一個屬性映射,以期望 dateStr.ln = "zh" 這樣賦值
class DateString extends HTMLElement { ... get ln () { return this.getAttribute("ln") } set ln (value) { this.setAttribute("ln", value) } }元素升級
除了像上面那樣用 JavaScript 代碼創(chuàng)建元素并添加到 body 下面,也可以直接在 HTML 寫自定義元素
Document
上面的代碼依然正常工作。首先瀏覽器正常解析文檔,遇到
需要注意的是,只有插入到文檔中的元素才會升級:
派生內(nèi)置元素類型Document
除了從 HTMLElement 派生自定義元素,我們還可以從 HTMLButtonElement, HTMLDivElement 等內(nèi)置元素類型派生自定義元素。這么做的好處是,可以保留內(nèi)置元素的語義化功能。比如,HTMLButtonElement 有 active 狀態(tài),通過按 tab 鍵可以使 button 元素獲得焦點,然后按回車鍵相當于點擊 button 元素?,F(xiàn)在我們從 HTMLButtonElement 派生一個自定義的按鈕,并在點擊的時候改變背景顏色。
Document
這個按鈕在行為上與內(nèi)置的 button 一樣, 可以獲取焦點,提交表單,也有禁用屬性等。
派生內(nèi)置元素與自定義元素略微不同,調(diào)用 customElements.define 時要傳入第三個參數(shù)表明是從那個元素派生,這里使用的名稱是 "button" 即標簽名,因為瀏覽器是靠識別標簽名來提供語義和默認行為,基于這一點,使用的時候也是用的原本的標簽名 button,然后再給一個 is 屬性指定自定義元素的名稱。
通過 document.createElement 創(chuàng)建元素時也有不同
const coloredButton = document.createElement("button", { is: "colored-button" })
也可以直接調(diào)用構(gòu)造函數(shù)創(chuàng)建
const coloredButton = new ColoredButton console.log(coloredButton.localName) // => "button" console.log(coloredButton.getAttribute(is)) // => "colored-button"
注:直到 chrome 61 版本,擴展內(nèi)置元素依然在開發(fā)中。參見鏈接
構(gòu)造函數(shù)的一些限制自定義元素的構(gòu)造函數(shù)必須遵循如下限制
構(gòu)造函數(shù)中不能調(diào)用 document.write() 和 document.open()
不能訪問元素的屬性和子元素,因為在元素未升級的情況下(元素還未插入文檔中),不存在屬性和子元素
初始化工作要盡量推遲到 connectedCallback 中,尤其是涉及獲取資源或渲染的工作。但是 connectedCallback 可能會調(diào)用多次(每次插入到文檔中時都會調(diào)用),一次性的初始化工作需要自己設置防護措施。
命名限制自定義元素的命名限制如下
必須以小寫字母開頭
必須有至少一個中劃線
允許小寫字母,中劃線,下劃線,點號,數(shù)字
允許部分 Unicode 字符,所以
不允許下面這些名稱
annotation-xml
color-profile
font-face
font-face-src
font-face-uri
font-face-format
font-face-name
missing-glyph
如果名稱出現(xiàn)不允許的字符, customElements.define 會報錯。
生命周期函數(shù)自定義元素可以定義特殊生命周期鉤子,以便在其存續(xù)的特定時間內(nèi)運行代碼。
constructor 創(chuàng)建或升級元素的一個實例。用于初始化狀態(tài)、設置事件偵聽器。
connectedCallback 元素每次插入到 DOM 時都會調(diào)用。可用于獲取資源或渲染。
disconnectedCallback 元素每次從 DOM 中移除時都會調(diào)用。用于運行清理代碼。
attributeChangedCallback 屬性添加、移除、更新或替換。僅對 observedAttributes 中返回的屬性有效。
adoptedCallback 自定義元素被移入新的 document 時調(diào)用。
響應回調(diào)是同步的。如果有人對您的元素調(diào)用 el.setAttribute(...),瀏覽器將立即調(diào)用 attributeChangedCallback()。 同理,從 DOM 中移除元素(例如用戶調(diào)用 el.remove())后,您會立即收到 disconnectedCallback()。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88907.html
摘要:明確各階段適合的操作用于初始化元素的狀態(tài)和設置事件監(jiān)聽,或者創(chuàng)建。事件類型轉(zhuǎn)換通過捕獲事件,然后通過發(fā)起事件來對事件類型進行轉(zhuǎn)換,從而觸發(fā)更符合元素特征的事件類型。 前言 ?通過《WebComponent魔法堂:深究Custom Element 之 面向痛點編程》,我們明白到其實Custom Element并不是什么新東西,我們甚至可以在IE5.5上定義自己的alert元素。但這種簡單...
摘要:若自定義元素標簽名稱不可用則摒棄??傊?,自定義元素讓開發(fā)者的代碼更易理解和維護,并分割為小型,可復用及可封裝的模塊。被稱為自定義元素接口,雖然現(xiàn)在仍然可用,但是已經(jīng)被棄用并被認為是糟糕的實現(xiàn)。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 這是 JavaScript 工作原理第十九章。 概述 在 前述文章中,我們介紹了 Shadow ...
摘要:以下是關(guān)于中一些模塊的概要以及它們與這篇文章的關(guān)聯(lián)性這個模塊實現(xiàn)了我們在這篇文章中討論的關(guān)于的幾個回調(diào)函數(shù),同時它還會初始化一個策略類,這個類會作為連接和的橋梁。 現(xiàn)在,Angular Elements 這個項目已經(jīng)在社區(qū)引起一定程度的討論。這是顯而易見的,因為 Angular Elements 提供了很多開箱即用的、十分強大的功能: 通過使用原生的 HTML 語法來使用 Angul...
摘要:通過創(chuàng)建元素時也有不同也可以直接調(diào)用構(gòu)造函數(shù)創(chuàng)建注直到版本,擴展內(nèi)置元素依然在開發(fā)中。自定義元素被移入新的時調(diào)用。 很早我們就可以在 HTML 文檔中寫 這樣的自定義名稱標簽。但是瀏覽器對于不認識的標簽一律當成一個普通的行內(nèi)元素處理,沒有相關(guān)語義。雖然我們能用 JavaScript 代碼給它添加一些功能,但是并沒有生命周期相關(guān)的函數(shù)供我們做一些初始化和銷毀的處理。 通過瀏覽器提供...
閱讀 2150·2021-11-16 11:45
閱讀 1276·2021-10-22 09:53
閱讀 4046·2021-09-07 10:26
閱讀 1248·2021-09-06 15:00
閱讀 2101·2019-08-28 18:09
閱讀 2843·2019-08-26 14:06
閱讀 4033·2019-08-26 13:48
閱讀 1332·2019-08-26 12:11