法:
//添加到容器(父級節(jié)點)的結(jié)尾,并返回新增節(jié)點
parentNode.appendChild(新節(jié)點);
//參照節(jié)點之前插入節(jié)點,并返回新節(jié)點
parentNode.insertBefore(新節(jié)點,參照節(jié)點)
//用新節(jié)點替換當(dāng)前節(jié)點,并返回被替換節(jié)點(當(dāng)前節(jié)點)
parentNode.replaceChild (新節(jié)點,當(dāng)前節(jié)點 )
//移除節(jié)點,并返回移除的節(jié)點
//不能直接刪除自己,是需要先到父級元素,再來刪除自己
parentNode.removeChild(當(dāng)前元素)
//克隆節(jié)點,返回一個被克隆的新節(jié)點
//一個布爾值參數(shù),默認(rèn)false為淺拷貝,只復(fù)制容器,true為深拷貝,包括內(nèi)容全部復(fù)制
被克隆的元素.cloneNode(true|false)
html和css代碼
<button id="btn">最前插入新節(jié)點</button>
<ul id="uu">
<li>桃園豪杰三結(jié)義 <button class="rep">替換</button> <button class="del">刪除</button></li>
<li>孫堅跨江擊劉表 <button class="rep">替換</button> <button class="del">刪除</button></li>
<li>呂奉先射戟轅門 <button class="rep">替換</button> <button class="del">刪除</button></li>
<li>關(guān)公賺城斬車胄 <button class="rep">替換</button> <button class="del">刪除</button></li>
<li>玄德荊州依劉表 <button class="rep">替換</button> <button class="del">刪除</button></li>
<li>趙子龍單騎救主 <button class="rep">替換</button> <button class="del">刪除</button></li>
<li>諸葛亮痛哭龐統(tǒng) <button class="rep">替換</button> <button class="del">刪除</button></li>
<li>關(guān)云長敗走麥城 <button class="rep">替換</button> <button class="del">刪除</button></li>
<li>武侯彈琴退仲達(dá) <button class="rep">替換</button> <button class="del">刪除</button></li>
<li>魏主政歸司馬氏 <button class="rep">替換</button> <button class="del">刪除</button></li>
</ul>
JavaScript代碼
文為Varlet組件庫源碼主題閱讀系列第六篇,Varlet支持自定義主題及暗黑模式,本篇文章我們來詳細(xì)看一下這兩者的實現(xiàn)。
Varlet是通過css變量來組織樣式的,什么是css變量呢,其實很簡單,首先聲明自定義的css屬性,隨便聲明在哪個元素上都可以,不過只有該元素的后代才能使用,所以如果要聲明全局所有元素都能使用的話,可以設(shè)置到根偽類:root下:
:root {
--main-bg-color: red;
}
如代碼所示,css變量的自定義屬性是有要求的,需要以--開頭。
然后在任何需要使用該樣式的元素上通過var()函數(shù)調(diào)用即可:
div {
background-color: var(--main-bg-color);
}
只要更改了--main-bg-color屬性的值,所有使用該樣式變量的地方都會更新,所以主題定制靠的就是這個。
Varlet組件的樣式變量總體分為兩種:基本的、組件自身的。
公共的基本樣式變量定義在varlet-ui/src/styles/目錄下:
每個組件都會引入這個文件,比如Button組件:
除此之外每個組件也會有自身的變量,同樣比如Button組件:
想要修改默認(rèn)的值也很簡單,直接覆蓋即可。運(yùn)行時動態(tài)更新樣式也可以直接修改根節(jié)點的樣式變量,此外Varlet也提供了一個組件來幫我們做這件事,接下來看看這個組件是怎么實現(xiàn)的。
組件式調(diào)用可以有范圍性的定制組件樣式,避免全局污染,使用示例:
<script setup>
import { ref, reactive } from 'vue'
const state = reactive({
score: 5,
})
const styleVars = ref({
'--rate-primary-color': 'var(--color-success)',
})
</script>
<template>
<var-style-provider :style-vars="styleVars">
<var-rate v-model="state.score" />
</var-style-provider>
</template>
StyleProvider組件源碼如下:
<script lang="ts">
import { defineComponent, h } from 'vue'
import { formatStyleVars } from '../utils/elements'
import { call, createNamespace } from '../utils/components'
const { n } = createNamespace('style-provider')
export default defineComponent({
name: 'VarStyleProvider',
props: {
styleVars: {
type: Object,
default: () => ({}),
},
},
setup(props, { slots }) {
return () =>
h(
'div',
{
class: n(),
style: formatStyleVars(props.styleVars),
},
call(slots.default)
)
},
})
</script>
實現(xiàn)很簡單,就是創(chuàng)建一個div元素來包裹組件,然后將css變量設(shè)置到該div上,這樣這些css變量只會影響它的子孫元素。
除了使用組件,也可以通過函數(shù)的方式使用,但是只能全局更新樣式:
<script setup>
import { StyleProvider } from '@varlet/ui'
let rootStyleVars = null
const darkTheme = {
'--color-primary': '#3f51b5'
}
const toggleRootTheme = () => {
rootStyleVars = rootStyleVars ? null : darkTheme
StyleProvider(rootStyleVars)
}
</script>
<template>
<var-button type="primary" block @click="toggleRootTheme">切換根節(jié)點樣式變量</var-button>
</template>
StyleProvider函數(shù)如下:
const mountedVarKeys: string[] = []
function StyleProvider(styleVars: StyleVars | null = {}) {
// 刪除之前設(shè)置的css變量
mountedVarKeys.forEach((key) => document.documentElement.style.removeProperty(key))
mountedVarKeys.length = 0
// 將css變量設(shè)置到根元素上,并且添加到mountedVarKeys數(shù)組
const styles: StyleVars = formatStyleVars(styleVars)
Object.entries(styles).forEach(([key, value]) => {
document.documentElement.style.setProperty(key, value)
mountedVarKeys.push(key)
})
}
實現(xiàn)也非常簡單,直接將css變量設(shè)置到html節(jié)點上,同時會添加到一個數(shù)組里,用于刪除操作。
Varlet內(nèi)置提供了暗黑模式的支持,使用方式為:
<script setup>
import dark from '@varlet/ui/es/themes/dark'
import { StyleProvider } from '@varlet/ui'
let currentTheme = null
const toggleTheme = () => {
currentTheme = currentTheme ? null : dark
StyleProvider(currentTheme)
}
</script>
<template>
<var-button block @click="toggleTheme">切換主題</var-button>
</template>
也調(diào)用了前面的StyleProvider方法,所以實現(xiàn)原理也是通過css變量,其實就是內(nèi)置了一套暗黑模式的css變量:
可以發(fā)現(xiàn)使用css變量來實現(xiàn)主題定制和暗黑模式是非常簡單的,兼容性也非常好,各位如果有涉及到換膚的需求都可以優(yōu)先考慮使用。
HTML DOM 節(jié)點
在 HTML DOM (Document Object Model) 中 , 每一個元素都是 節(jié)點:
文檔是一個文檔。
所有的HTML元素都是元素節(jié)點。
所有 HTML 屬性都是屬性節(jié)點。
文本插入到 HTML 元素是文本節(jié)點。are text nodes。
注釋是注釋節(jié)點。
Document 對象
當(dāng)瀏覽器載入 HTML 文檔, 它就會成為 document 對象。
document 對象是HTML文檔的根節(jié)點與所有其他節(jié)點(元素節(jié)點,文本節(jié)點,屬性節(jié)點, 注釋節(jié)點)。
Document 對象使我們可以從腳本中對 HTML 頁面中的所有元素進(jìn)行訪問。
提示:Document 對象是 Window 對象的一部分,可通過 window.document 屬性對其進(jìn)行訪問。
瀏覽器支持
所有主要瀏覽器都支持 Document 對象。
Document 對象屬性和方法
HTML文檔中可以使用以上屬性和方法:
屬性 / 方法 | 描述 |
---|---|
document.activeElement | 返回當(dāng)前獲取焦點元素 |
document.addEventListener() | 向文檔添加句柄 |
document.adoptNode(node) | 從另外一個文檔返回 adapded 節(jié)點到當(dāng)前文檔。 |
document.anchors | 返回對文檔中所有 Anchor 對象的引用。 |
document.applets | 返回對文檔中所有 Applet 對象的引用。 |
document.baseURI | 返回文檔的絕對基礎(chǔ) URI |
document.body | 返回文檔的body元素 |
document.close() | 關(guān)閉用 document.open() 方法打開的輸出流,并顯示選定的數(shù)據(jù)。 |
document.cookie | 設(shè)置或返回與當(dāng)前文檔有關(guān)的所有 cookie。 |
document.createAttribute() | 創(chuàng)建一個屬性節(jié)點 |
document.createComment() | createComment() 方法可創(chuàng)建注釋節(jié)點。 |
document.createDocumentFragment() | 創(chuàng)建空的 DocumentFragment 對象,并返回此對象。 |
document.createElement() | 創(chuàng)建元素節(jié)點。 |
document.createTextNode() | 創(chuàng)建文本節(jié)點。 |
document.doctype | 返回與文檔相關(guān)的文檔類型聲明 (DTD)。 |
document.documentElement | 返回文檔的根節(jié)點 |
document.documentMode | 返回用于通過瀏覽器渲染文檔的模式 |
document.documentURI | 設(shè)置或返回文檔的位置 |
document.domain | 返回當(dāng)前文檔的域名。 |
document.domConfig | 返回normalizeDocument()被調(diào)用時所使用的配置 |
document.embeds | 返回文檔中所有嵌入的內(nèi)容(embed)集合 |
document.forms | 返回對文檔中所有 Form 對象引用。 |
document. getElementsByClassName() | 返回文檔中所有指定類名的元素集合,作為 NodeList 對象。 |
document.getElementById() | 返回對擁有指定 id 的第一個對象的引用。 |
document.getElementsByName() | 返回帶有指定名稱的對象集合。 |
document.getElementsByTagName() | 返回帶有指定標(biāo)簽名的對象集合。 |
document.images | 返回對文檔中所有 Image 對象引用。 |
document.implementation | 返回處理該文檔的 DOMImplementation 對象。 |
document.importNode() | 把一個節(jié)點從另一個文檔復(fù)制到該文檔以便應(yīng)用。 |
document.inputEncoding | 返回用于文檔的編碼方式(在解析時)。 |
document.lastModified | 返回文檔被最后修改的日期和時間。 |
document.links | 返回對文檔中所有 Area 和 Link 對象引用。 |
document.normalize() | 刪除空文本節(jié)點,并連接相鄰節(jié)點 |
document.normalizeDocument() | 刪除空文本節(jié)點,并連接相鄰節(jié)點的 |
document.open() | 打開一個流,以收集來自任何 document.write() 或 document.writeln() 方法的輸出。 |
document.querySelector() | 返回文檔中匹配指定的CSS選擇器的第一元素 |
document.querySelectorAll() | document.querySelectorAll() 是 HTML5中引入的新方法,返回文檔中匹配的CSS選擇器的所有元素節(jié)點列表 |
document.readyState | 返回文檔狀態(tài) (載入中……) |
document.referrer | 返回載入當(dāng)前文檔的文檔的 URL。 |
document.removeEventListener() | 移除文檔中的事件句柄(由 addEventListener() 方法添加) |
document.renameNode() | 重命名元素或者屬性節(jié)點。 |
document.scripts | 返回頁面中所有腳本的集合。 |
document.strictErrorChecking | 設(shè)置或返回是否強(qiáng)制進(jìn)行錯誤檢查。 |
document.title | 返回當(dāng)前文檔的標(biāo)題。 |
document.URL | 返回文檔完整的URL |
document.write() | 向文檔寫 HTML 表達(dá)式 或 JavaScript 代碼。 |
document.writeln() | 等同于 write() 方法,不同的是在每個表達(dá)式之后寫一個換行符。 |
警告 !!!
在 W3C DOM核心,文檔對象 繼承節(jié)點對象的所有屬性和方法。
很多屬性和方法在文檔中是沒有意義的。
HTML 文檔對象可以避免使用這些節(jié)點對象和屬性:
屬性 / 方法 | 避免的原因 |
---|---|
document.attributes | 文檔沒有該屬性 |
document.hasAttributes() | 文檔沒有該屬性 |
document.nextSibling | 文檔沒有下一節(jié)點 |
document.nodeName | 這個通常是 #document |
document.nodeType | 這個通常是 9(DOCUMENT_NODE) |
document.nodeValue | 文檔沒有一個節(jié)點值 |
document.ownerDocument | 文檔沒有主文檔 |
document.ownerElement | 文檔沒有自己的節(jié)點 |
document.parentNode | 文檔沒有父節(jié)點 |
document.previousSibling | 文檔沒有兄弟節(jié)點 |
document.textContent | 文檔沒有文本節(jié)點 |
如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。