1、节点类型
常用节点一共分为三种,分别是元素节点(element)、属性节点(attribute)、文本节点(text)。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="test">
</div>
</body>
</html>
<script>
const elementNode = document.getElementById('test')
const attrNode = elementNode.getAttributeNode('id')
const textNode = elementNode.firstChild
console.log(elementNode.nodeType) // 1 元素节点
console.log(attrNode.nodeType) // 2 元素节点
console.log(textNode.nodeType) // 3 文本节点
</script>
2、Object.defineProperty
给对象添加属性:
Object.defineProperty(obj,prop,{descriptor})
obj:要定义属性的对象
prop:要定义或修改的属性名称
descriptor:属性的描述信息
属性描述符:
1)configurable: (属性)是否可重新定义
2)enumerable: (属性)是否可枚举
3)value: (属性)对应的初始值
4)writable: (属性)是否可被修改
let obj = {
firstName:'A',
lastName:'B'
}
Object.defineProperty(obj,'fullName',{
configurable: true, // 可以重新定义属性
enumerable:false,// 不能枚举属性
value:'G-H',
writable:false // 不能修改属性
})
//writable
console.log(obj.fullName) //value G-H
obj.fullName = 'J-K'//修改了属性值
console.log(obj.fullName)//仍旧是G-H,不可修改
//configurable
Object.defineProperty(obj,'fullName',{
enumerable:false,
value:'M-N',
}) //如果configurable设置为false,则会抛异常-->TypeError: Cannot redefine property: fullName
//enumerable
const names = Object.keys(obj)
console.log(names) //[ 'firstName', 'lastName' ],fullName属性无法枚举出来
访问描述符:
5)get: 回调函数,根据其他相关的属性,动态计算得到当前属性值
6)set: 回调函数,监视当前属性值的变化,更新其他相关属性
Object.defineProperty(obj,'fullName',{
get(){
return this.firstName + '-' + this.lastName
},
set(val){
const names = val.split('-')
this.firstName = names[0]
this.lastName = names[1]
}
})
//get
console.log(obj.fullName) // A-B
obj.firstName = 'C'
obj.lastName = 'D'
console.log(obj.fullName) // C-D get动态获取值
//set
obj.fullName = 'E-F'
console.log(obj.firstName,obj.lastName) //E F
3、obj.hasOwnProperty(prop)
判断对象自身属性中,是否具有指定的属性
var obj = {
firstName: 'A'
}
console.log(obj.hasOwnProperty('firstName')) // true
console.log(obj.hasOwnProperty('toString')) // false
4、文档碎片DocumentFragment
文档碎片的api可以参考这篇文档:
https://developer.mozilla.org/zh-CN/docs/Web/API/DocumentFragment
document和fragment的区别:
document:对应显示的页面,包含n个element,一旦更新了document内部的某个元素,整个界面都要更新;
fragment:内存中保存n个element的容器,不与界面关联,如果更新fragment中的某个element,界面不变。
有了文档碎片,我们就可以更为高效的批量更新多个节点了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<ul id="frag">
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
</div>
</body>
</html>
<script>
//document:对应显示的页面,包含n个element,一旦更新了document内部的某个元素,整个界面都要更新
//documentFragment:内存中保存n个element的容器,不与界面关联,如果更新fragment中的某个element,界面不变
const ul = document.getElementById('frag')
console.log(ul.innerHTML)
//1.创建fragment
const fragment = document.createDocumentFragment()
//2.取出ul中所有子节点,(包含换行等文本子节点)
let child = null
while (child = ul.firstChild) { // 一个节点只有一个父亲(节点或隶属document,或隶属fragment,二选一)
fragment.appendChild(child) // 先将child从document移除,然后放入fragment
} //每迭代一次,ul中的节点出栈
console.log(ul.innerHTML) // 空,已经将节点全部转移到fragment中了
//3.更新fragment中的所有li的内容
let nodes = [].slice.call(fragment.childNodes)
nodes.forEach(node => {
if (node.nodeType === 1) {
node.textContent = 'hello'
}
})
//4.将fragment插回ul
ul.appendChild(fragment)
</script>
网友评论