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