遍历节点树
节点包含元素->元素节点=DOM 元素
- parentNode
childNodes// 包含 元素节点(类型 1) 属性节点(类型 2) 文本节点(包括换行 类型 3) 注释节点(类型 8) document(类型 9) documentFragment(类型 11)类型- firstChild lastChild
- nextSibling previousSibling 选择下一个 上一个节点
// 封装方法使得childNodes只返回元素节点
// nodeName可以取得节点的名字 不是tagName
// 属性节点没有nodeValue 属性、注释、文本节点有nodeValue属性且可修改
//nodeType 只读
function elementChildren(node) {
let arr = [],
children = node.childrenNodes;
for (let i = 0; i < children.lenth; i++) {
let tempNode = children[i];
if (tempNode.nodeType === 1) {
arr.push(tempNode);
}
}
return arr;
}
遍历元素节点树
这个有兼容性问题
- parentElement //IE9 及以下不支持
- children //IE7 及以下不支持
- childrenElementCount = children.length //IE9 及以下不支持
- firstElementChild lastElementChild //IE9 及以下不支持
- nextElementSibling //IE9 及以下不支持 previousElementSibling //IE9 及以下不支持
节点选择的过程
function getElementsByTagNames(ele) {
// 以选择p元素为例
// 1.从HTML中把p元素选择出来
// 2.调用new HTMLParagraphElement()生成Dom元素节点并返回该对象 这样该对象就具有了nodeName nodeType等属性
}
- getElementById()只在
Document上有 - getElementsByName
Element上没有因此
<div>
<div> </div>
</div>;
const div = document.getElementsByTagName("div")[0];
div.getElementsById(); //会报错的,因为div由HTMLDivElement构造生成
- getElementByTagName、getElementByClassName、querySelector、querySelectorAll
Document和Element都有 - HTMLDocument.prototype 上的 body 和 head 属性指向
<head>和<body>标签 - Document.prototype 上的 doucmentElement 指向 HTML 标签
练习题原型上添加一个函数获取元素节点的子元素,参数可传可不传,不传的话返回类数组,传的话返回那个 index 的子元素
Element.prototype.eleChildren = function (num = null) {
let childrenNode = this.childNodes;
let elementNode = {
// splice: Array.prototype.splice,
push: Array.prototype.push,
length: 0,
};
for (let i = 0; i < childrenNode.length; i++) {
let tempNode = childrenNode[i];
if (tempNode.nodeType === 1) {
elementNode.push(tempNode);
}
}
return num ? elementNode[num] : elementNode;
};
const ulDom = document.getElementsByTagName("ul")[0];
节点创建删除
Element 上没有
- doucument.createElement()
- document.createTextNode()
- document.createComment
增加/剪切子节点
appendChild() 在 Node.prototype 上
总是在插入节点的最后,如果插入的节点是本身就是在 dom 上的节点,则会把原节点剪切到指定位置
在指定位置之前插入
c.insertBefore(a,b)
在父级 c 节点下的子节点 b 之前插入 a 节点
该方法是Node.prototype上的方法
删除子节点
父节点.removeChild(子节点) 这个只是把 dom 树上的该节点移除 但是没有释放创建这个节点的内存 而节点自身.remove()则真正销毁并释放内存
innerHTML 和 innerText
这俩方法 HTMLElement.prototype 上都有 Element.prototype 上只有 innerHTML
setAttribute(属性名,属性值)
自定义属性
HTML5 给元素增加了一个 data-*属性
获取时使用元素节点.dataset 可以获取到自定义属性对象 key 为你自己定义的*
创建文档片段
doucment.createDocumentFragment()
fragment 节点 type 是 11 他不是 dom 元素节点所以插入他的话不会在原有 DOM 元素树上插入额外的元素节点,因此 fragment 最适合作为其他要插入的元素节点的外层容器(不会引起页面回流)