DOM概述
- JS = ECMAScript(核心语法) + DOM(专门操作网页的API) + BOM(专门操作浏览器窗口的API)
- DHTML : 所有实现网页动态效果的统称, 即HTML + CSS + JS
- DOM: 操作一切结构化文档的通用API, 即用DOM可操作HTML, 也可操作XML
- 核心DOM: 可以操作所有文档的通用API, 可实现增删改查等所有功能, 但操作繁琐
- HTML DOM: 基于核心DOM的API, 扩展的专门操作HTML的API, 简单易用, 重点简化了修改操作, 对个别复杂HTML元素扩展了简化方法
- 注意: 开发中, 修改时可用HTML DOM, 并且优先使用HTML DOM, 查、增、删时只能使用核心DOM
DOM Tree
- 网页加载行为
- 网页加载进内存时, 会先创建一个document对象, 指代当前网页
- 网页中的所有内容: 元素、文本、属性、注释等都叫节点对象
- document作为DOM Tree的根节点, 所有节点对象都是document对象的子节点
- 节点对象的类型:
- document对象: 文档类型(Document)
- 元素节点: 元素类型(Element)
- 文本节点: 文本类型(Text)
- 属性节点: 属性类型(Attr)
- Node类型: 是所有节点的父类型
- 3个通用属性:
- nodeType: 获得当前节点的类型, 返回的是一个数字, 用于区分不同的节点类型
- ELEMENT_NODE: 1
- ATTRIBUTE_NODE: 2
- TEXT_NODE: 3
- DOCUMENT_NODE: 9
- nodeName: 获得当前节点的名称, 用于区分不同的元素节点
- 元素节点, 返回全大写字母标签名
- 文本节点, 返回text
- 文档节点, 返回document
- nodeValue: 获得当前节点的值, 对元素节点无效
- 元素节点, 返回null
- 文本节点, 返回文本内容
- 属性节点, 返回属性值
- nodeType: 获得当前节点的类型, 返回的是一个数字, 用于区分不同的节点类型
- 3个通用属性:
- DOM Tree中的6种关系
- 父子关系类: parentNode、childNodes、firstChild、lastChild
- childNodes: NodeList集合——类数组对象
- 动态集合: 不包含结果对象的完整属性, 仅保存对象的引用, 每次使用, 都重复查询
- 兄弟关系类: previousSibling、nextSibing
- 注意: 上述6种关系, 除parentNode外, 都会受看不见的空字符的干扰
- 父子关系类: parentNode、childNodes、firstChild、lastChild
- DOM Tree的遍历
- 节点树: 包含所有节点对象的树结构
- 遍历节点树: 深度优先算法, 递归调用
- 遍历元素树: 仅包含元素节点的树结构, 仅是节点树的子集, 存在兼容性问题
- arguments.callee: 指代当前函数对象
- 何时使用: 多用于在递归调用内部取代当前函数名
节点树 | 元素树 | |
---|---|---|
父节点 | parentNode | parentElementNode |
所有子节点 | childNodes | children |
第一个子节点 | firstChild | firstElementChild |
最后一个子节点 | lastChild | lastElementChild |
前一个兄弟 | previousSibling | previousElementSibling |
后一个兄弟 | nextSibling | nextElementSibling |
- DOM Tree遍历API: NodeIterator、TreeWalker —— 详见博客另一篇文章“遍历DOM(NodeIterator和TreeWalker的使用)”
- 内部同样使用深度优先算法
- 步骤: 2步
- 创建迭代器对象: var iterator = document.creatNodeIterator(root, whatToShow, filter,entityReferenceExpansion);
- 注意: 迭代器开始时, 站在第一个节点的前一个位置
- 2个方法:
- iterator.nextNode() 让迭代器向下一个对象跳一步, 同时返回跳到的对象, 如果没有下一个节点了, 则返回null
- iterator.previousNode
- 利用循环推动迭代器反复向下一个节点移动
- 创建迭代器对象: var iterator = document.creatNodeIterator(root, whatToShow, filter,entityReferenceExpansion);
- NodeIterator和TreeWalker异同
- 相同点: 创建和遍历的方法完全一样
- 区别一: Iterator一开始站在开始节点之前的空位置, TreeWalker一开始就站在开始节点上
- 区别二: 扩展了更灵活的跳转方法 —— parentNode()、firstChild()、nextSibling()等
查找元素节点
- 按HTML属性查找
- 无兼容性问题的API
- document.getElementById(“id值”)
- parent.getElementsByTagName(“标签名”);
- parent.getElementsByName(“name属性”);
- IE8不兼容的API
- parent.getElementsByClassName(“class名”)
- 注意: getElementsXXX, 返回HTMLCollection —— 动态集合
- 无兼容性问题的API
- Selector API: 专门利用css选择器查找任意元素的方法 —— jQuery的核心
- parent.querySelector(“选择器”); 只返回第一个匹配的元素
- parent.querySelectorAll(“选择器”); 返回所有符合选择器的元素对象, 是包含完整对象属性的集合 —— 非动态集合
获取或修改元素的内容
- innerHTML: 获得/设置元素开始标签和结束标签之间的HTML原文
- 何时使用: 获取或修改元素的HTML原文时
- 固定套路:
- 批量删除父元素下所有子节点: elem.innerHTML=”“;
- 批量替换父元素下所有节点: elem.innerHTML=”所有子元素标签组成的HTML字符串”
- textContent: 获得或设置元素开始标签和结束标签之间的转化后的正文内容
- IE8不兼容, 可替换为innerText