法:
//添加到容器(父级节点)的结尾,并返回新增节点
parentNode.appendChild(新节点);
//参照节点之前插入节点,并返回新节点
parentNode.insertBefore(新节点,参照节点)
//用新节点替换当前节点,并返回被替换节点(当前节点)
parentNode.replaceChild (新节点,当前节点 )
//移除节点,并返回移除的节点
//不能直接删除自己,是需要先到父级元素,再来删除自己
parentNode.removeChild(当前元素)
//克隆节点,返回一个被克隆的新节点
//一个布尔值参数,默认false为浅拷贝,只复制容器,true为深拷贝,包括内容全部复制
被克隆的元素.cloneNode(true|false)
html和css代码
<button id="btn">最前插入新节点</button>
<ul id="uu">
<li>桃园豪杰三结义 <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>关公赚城斩车胄 <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>诸葛亮痛哭庞统 <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>魏主政归司马氏 <button class="rep">替换</button> <button class="del">删除</button></li>
</ul>
JavaScript代码
文为Varlet组件库源码主题阅读系列第六篇,Varlet支持自定义主题及暗黑模式,本篇文章我们来详细看一下这两者的实现。
Varlet是通过css变量来组织样式的,什么是css变量呢,其实很简单,首先声明自定义的css属性,随便声明在哪个元素上都可以,不过只有该元素的后代才能使用,所以如果要声明全局所有元素都能使用的话,可以设置到根伪类:root下:
:root {
--main-bg-color: red;
}
如代码所示,css变量的自定义属性是有要求的,需要以--开头。
然后在任何需要使用该样式的元素上通过var()函数调用即可:
div {
background-color: var(--main-bg-color);
}
只要更改了--main-bg-color属性的值,所有使用该样式变量的地方都会更新,所以主题定制靠的就是这个。
Varlet组件的样式变量总体分为两种:基本的、组件自身的。
公共的基本样式变量定义在varlet-ui/src/styles/目录下:
每个组件都会引入这个文件,比如Button组件:
除此之外每个组件也会有自身的变量,同样比如Button组件:
想要修改默认的值也很简单,直接覆盖即可。运行时动态更新样式也可以直接修改根节点的样式变量,此外Varlet也提供了一个组件来帮我们做这件事,接下来看看这个组件是怎么实现的。
组件式调用可以有范围性的定制组件样式,避免全局污染,使用示例:
<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>
实现很简单,就是创建一个div元素来包裹组件,然后将css变量设置到该div上,这样这些css变量只会影响它的子孙元素。
除了使用组件,也可以通过函数的方式使用,但是只能全局更新样式:
<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">切换根节点样式变量</var-button>
</template>
StyleProvider函数如下:
const mountedVarKeys: string[] = []
function StyleProvider(styleVars: StyleVars | null = {}) {
// 删除之前设置的css变量
mountedVarKeys.forEach((key) => document.documentElement.style.removeProperty(key))
mountedVarKeys.length = 0
// 将css变量设置到根元素上,并且添加到mountedVarKeys数组
const styles: StyleVars = formatStyleVars(styleVars)
Object.entries(styles).forEach(([key, value]) => {
document.documentElement.style.setProperty(key, value)
mountedVarKeys.push(key)
})
}
实现也非常简单,直接将css变量设置到html节点上,同时会添加到一个数组里,用于删除操作。
Varlet内置提供了暗黑模式的支持,使用方式为:
<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>
也调用了前面的StyleProvider方法,所以实现原理也是通过css变量,其实就是内置了一套暗黑模式的css变量:
可以发现使用css变量来实现主题定制和暗黑模式是非常简单的,兼容性也非常好,各位如果有涉及到换肤的需求都可以优先考虑使用。
HTML DOM 节点
在 HTML DOM (Document Object Model) 中 , 每一个元素都是 节点:
文档是一个文档。
所有的HTML元素都是元素节点。
所有 HTML 属性都是属性节点。
文本插入到 HTML 元素是文本节点。are text nodes。
注释是注释节点。
Document 对象
当浏览器载入 HTML 文档, 它就会成为 document 对象。
document 对象是HTML文档的根节点与所有其他节点(元素节点,文本节点,属性节点, 注释节点)。
Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。
提示:Document 对象是 Window 对象的一部分,可通过 window.document 属性对其进行访问。
浏览器支持
所有主要浏览器都支持 Document 对象。
Document 对象属性和方法
HTML文档中可以使用以上属性和方法:
属性 / 方法 | 描述 |
---|---|
document.activeElement | 返回当前获取焦点元素 |
document.addEventListener() | 向文档添加句柄 |
document.adoptNode(node) | 从另外一个文档返回 adapded 节点到当前文档。 |
document.anchors | 返回对文档中所有 Anchor 对象的引用。 |
document.applets | 返回对文档中所有 Applet 对象的引用。 |
document.baseURI | 返回文档的绝对基础 URI |
document.body | 返回文档的body元素 |
document.close() | 关闭用 document.open() 方法打开的输出流,并显示选定的数据。 |
document.cookie | 设置或返回与当前文档有关的所有 cookie。 |
document.createAttribute() | 创建一个属性节点 |
document.createComment() | createComment() 方法可创建注释节点。 |
document.createDocumentFragment() | 创建空的 DocumentFragment 对象,并返回此对象。 |
document.createElement() | 创建元素节点。 |
document.createTextNode() | 创建文本节点。 |
document.doctype | 返回与文档相关的文档类型声明 (DTD)。 |
document.documentElement | 返回文档的根节点 |
document.documentMode | 返回用于通过浏览器渲染文档的模式 |
document.documentURI | 设置或返回文档的位置 |
document.domain | 返回当前文档的域名。 |
document.domConfig | 返回normalizeDocument()被调用时所使用的配置 |
document.embeds | 返回文档中所有嵌入的内容(embed)集合 |
document.forms | 返回对文档中所有 Form 对象引用。 |
document. getElementsByClassName() | 返回文档中所有指定类名的元素集合,作为 NodeList 对象。 |
document.getElementById() | 返回对拥有指定 id 的第一个对象的引用。 |
document.getElementsByName() | 返回带有指定名称的对象集合。 |
document.getElementsByTagName() | 返回带有指定标签名的对象集合。 |
document.images | 返回对文档中所有 Image 对象引用。 |
document.implementation | 返回处理该文档的 DOMImplementation 对象。 |
document.importNode() | 把一个节点从另一个文档复制到该文档以便应用。 |
document.inputEncoding | 返回用于文档的编码方式(在解析时)。 |
document.lastModified | 返回文档被最后修改的日期和时间。 |
document.links | 返回对文档中所有 Area 和 Link 对象引用。 |
document.normalize() | 删除空文本节点,并连接相邻节点 |
document.normalizeDocument() | 删除空文本节点,并连接相邻节点的 |
document.open() | 打开一个流,以收集来自任何 document.write() 或 document.writeln() 方法的输出。 |
document.querySelector() | 返回文档中匹配指定的CSS选择器的第一元素 |
document.querySelectorAll() | document.querySelectorAll() 是 HTML5中引入的新方法,返回文档中匹配的CSS选择器的所有元素节点列表 |
document.readyState | 返回文档状态 (载入中……) |
document.referrer | 返回载入当前文档的文档的 URL。 |
document.removeEventListener() | 移除文档中的事件句柄(由 addEventListener() 方法添加) |
document.renameNode() | 重命名元素或者属性节点。 |
document.scripts | 返回页面中所有脚本的集合。 |
document.strictErrorChecking | 设置或返回是否强制进行错误检查。 |
document.title | 返回当前文档的标题。 |
document.URL | 返回文档完整的URL |
document.write() | 向文档写 HTML 表达式 或 JavaScript 代码。 |
document.writeln() | 等同于 write() 方法,不同的是在每个表达式之后写一个换行符。 |
警告 !!!
在 W3C DOM核心,文档对象 继承节点对象的所有属性和方法。
很多属性和方法在文档中是没有意义的。
HTML 文档对象可以避免使用这些节点对象和属性:
属性 / 方法 | 避免的原因 |
---|---|
document.attributes | 文档没有该属性 |
document.hasAttributes() | 文档没有该属性 |
document.nextSibling | 文档没有下一节点 |
document.nodeName | 这个通常是 #document |
document.nodeType | 这个通常是 9(DOCUMENT_NODE) |
document.nodeValue | 文档没有一个节点值 |
document.ownerDocument | 文档没有主文档 |
document.ownerElement | 文档没有自己的节点 |
document.parentNode | 文档没有父节点 |
document.previousSibling | 文档没有兄弟节点 |
document.textContent | 文档没有文本节点 |
如您还有不明白的可以在下面与我留言或是与我探讨QQ群308855039,我们一起飞!
*请认真填写需求信息,我们会在24小时内与您取得联系。