【知识点】DOM和HTML树的定义和操作流程
优采云 发布时间: 2021-07-10 00:08【知识点】DOM和HTML树的定义和操作流程
内容
DOM 的定义
DOM 树
DOM树的定义
为什么是树状结构
根节点
节点对象
节点的三个属性
DOM 操作流程
DOM 查找
无需查找可以直接获取的元素
通过 HTML 搜索
按节点关系搜索
按选择器查找
遍历节点
DOM 搜索摘要
编辑
内容
属性
风格
添加
删除
替换
HTML DOM 常用对象
图片
选择
选项
表格
表格
DOM 的定义
用于操作 Web 内容的文档对象模型 API 标准-W3C
什么时候使用DOM
只要操作网页内容,就必须使用DOM提供的API
DOM 的分类
核心 DOM 和 HTML DOM
Core DOM:最初开发用于操作所有结构化文档的统一 API。优点:通用缺点:繁琐
HTML DOM:专门用于操作 HTML 文档的 API 优点:简洁缺点:不是万能的
总结:在实际开发中,不需要区分核心DOM和HTM LDOM。首选简单的 API。如果不能简单实现,就用复杂的补充
DOM 树
DOM树的定义
网页中的每一个内容都以树状结构存储在内存中,每一个内容(元素、文本、属性)都是树上的一个节点对象
为什么是树状结构
树结构是保存不确定层次深度的下级和下级收录关系的最佳结构
根节点
树结构有一个唯一的树根节点:文档节点。所有网页内容都是文档的子节点
节点对象
网页中的每一项都是一个节点对象,它封装了节点可用的属性和功能
节点的三个属性
nodeType:节点类型 nodeName:节点名称 nodeValue:节点值
节点类型:
功能:不同类型节点的可用属性和可执行操作不同。
包括4种类型:
文档 9
元素 1
属性 2
文本 3
问题:无法进一步区分特定元素名称
节点名称:
功能:进一步区分具体元素名称
包括4种类型:
文档#document
元素标签名称(全部大写)
attribute 属性名称
文本#文本
节点值:
功能:保存节点的值
包括4种类型:
文档为空
元素为空
attribute 属性值
文字文字内容
DOM 操作流程
增删改查+事件处理
找到触发事件的元素---->>绑定事件处理程序
找到要修改的元素---->>修改属性/样式,添加、删除
DOM 查找
1、无需寻找可以直接获取的元素
html document.documentElement
头文件.head
body document.body
2、HTML 搜索
1、通过id查找
var elem = document.getElementById("id"); //直接写id名称
强调:1、 必须与文档一起调用2、 只会返回一个元素
2、按标签名查找多个元素
var elems = document.getElementsByTagName("标签名");
重点:
1、可以在任何父元素上调用,即只查找当前父元素下的后代元素
2、不仅可以找到直接子元素,还可以找到所有后代元素
3、返回由多个元素组成的动态集合
3、按类属性搜索
var elems = document.getElementsByClassName("class");
重点:
1、 可以在任何父元素上调用
2、返回由多个元素组成的动态集合
3、只要收录指定的类名,选择要更改的元素。它不必完全匹配
4、不仅可以找到直接子元素,还可以找到所有后代元素
4、按名称属性搜索
var elems = document.getElementsByName("name");
name 属性只会在查找带有 name 属性的表单时使用
重点:
1、 只能用文档调用
2、返回由多个元素组成的动态集合
3、按节点关系搜索
何时使用:如果你已经获取了一个元素,你想找到周围的元素
1、父子关系
child.parentNode 获取节点的父节点
parent.childNodes 获取父节点下的所有直接子节点
parent.firstChild 获取父节点下的第一个子节点
parent.lastChild 获取父节点下的最后一个直接子节点
2、兄弟关系
elem.nextSibling 获取节点旁边的下一个兄弟节点
elem.previousSibling 获取与某个节点相邻的前一个兄弟节点
问题:我会被看不见的空字符打扰
解决方案:元素树
元素树:仅收录元素节点的树结构。元素树不是新树,只是节点树的部分子集
如何实现:
1、父子关系
child.parentElement 获取节点的父元素
parent.children 获取父元素下的所有直接子元素
parent.firstElementChild 获取父元素下的第一个直接子元素
parent.lastElementChild 获取父元素下的最后一个直接子元素
2、兄弟关系
elem.nextElementSibling 获取与元素相邻的下一个兄弟元素
elem.previousElementSibling 获取与元素相邻的前一个兄弟元素
4、通过选择器查找
1、只查找一个元素
var elem = parent.querySelector("selector");
2、查找多个元素
var elem = parent.querySelectorAll("selector");
重点:
1、 可以在任何父元素上调用
2、返回一个非动态集合(非动态集合:数据的实际存储,即重复访问,不会造成重复搜索DOM树)无首缓存长度的遍历
3、以当前浏览器的兼容性要求为准
5、traverse 节点
遍历节点定义:找到一个父元素下的所有后代节点
如何:
1、定义只遍历直接子节点的函数
2、 为遇到的每个子节点调用与父节点完全相同的操作
算法:深度优先(当同时有子元素和兄弟元素时,总是先遍历子元素。遍历完子元素后,返回兄弟元素)
问题:递归执行效率极低
解决方案:改用循环
操作方法:使用节点迭代器对象(NodeIterator专门按照深度优先遍历的顺序依次访问每个子元素的对象)
1、Create NodeIterator
var iterator = documnet.createNodeIterator(parent,NodeFilter.SHOW_ALL,null,false,SHOW_ELEMENT);
参数:
parent:树中要用作搜索起点的节点
NodeFilter.SHOW_ALL:显示所有类型的节点
NodeFilter.SHOW_ELEMENT:显示元素节点
NodeFilter.SHOW_TEXT:显示文本节点
NodeFilter.SHOW_COMMENT:显示评论节点
NodeFilter.SHOW_DOCUMENT:显示文档节点
2、循环调用NodeIterator的nextNode()函数
NodeIterator 的主要方法是 nextNode() 和 previousNode()
如何:
1.,返回当前节点
2.,跳转到下一个节点返回null退出
例如:
HTML 的结构:
你好
世界
遍历root下的所有元素:
var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, null, false);
var node = iterator.nextNode();
while(节点 !== null){
console.log( node.tagName );
node = iterator.nextNode();
}
遍历root下的所有p个元素:
var filter = function(node){
返回 node.tagName.toLowerCase() =='p' ?
NodeFilter.FILTER_ACCEPT:
NodeFilter.FILTER_REJECT;
}
var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, filter, false);
var node = iterator.nextNode();
while(节点 !== null){
console.log( node.tagName );
node = iterator.nextNode();
}
DOM 搜索摘要
1.如果已经获取到一个元素,则查找周围的元素:利用节点之间的关系来查找
2.如果传入一个条件,就可以找到你想要的元素:使用HTML搜索
3.如果搜索条件复杂:使用选择器API
按 HTML 与选择器
1.返回值:通过HTML搜索:返回动态集合
按选择器搜索:返回非动态集合
2.效率:第一次搜索通过HTML高效!
按选择器搜索有点慢!
3. 好用:按选择器搜索更简洁
HTML 搜索比较麻烦
编辑
1、content
.innerHTML .textContent .value
2、Attributes
标准属性:HTML 标准中规定的属性
1、Core DOM(4 个 API)
1、获取指定属性的值:
elem.getAttribute("属性名称")
2、修改指定属性的值:
elem.setAttribute("属性名", "值")
3、判断是否收录指定的属性:
elem.hasAttribute("属性名称")
4、去掉指定的属性:
elem.removeAttribute("属性名称")
2、HTML DOM:所有标准属性都预先封装在元素对象中,可以直接用“.”访问
1、获取指定属性的值:
elem.属性名称
2、修改指定属性的值:
elem.attribute name = "value"
3、判断是否收录指定的属性:
元素。属性名! ==""
4、去掉指定的属性:
elem.attribute name = ""
3、clas 属性
Class 是 E5 中的保留字,不能使用 DOM。使用 className 而不是 class
4、Status 属性
禁用选中选中
不能用核心 DOM 访问,只能用 HTML DOM 访问。值都是bool类型
5、自定义扩展属性(不能用HTML DOM访问自定义扩展属性)
1、核心DOM
2、HTML5:
定义属性:data-attribute name = "value"
访问:elem.dataset。属性名
3、style
1、内联
1、编辑:
elem.style.css 属性名称
css属性名必须从横线改成驼峰。优点:最高优先级,只有当前元素有自己的
2、阅读:
不能使用 style.css 属性名称。因为style只能获取内联样式,不能获取样式表中继承/级联的样式
解决方案:
以后,无论何时阅读一个样式,都必须阅读计算出的样式。 (计算样式:最终应用于元素的所有样式的合成,相对单位计算为绝对单位)
1、计算后得到所有css属性的总和:样式对象
var style = getComputedStyle(elem)
2、从样式中获取想要的css属性
style.css 属性
注意:计算出的样式是只读的,不能修改
问题:一句话只能修改一个css属性
解决方法:如何批量修改一个元素的多个属性:
1、先在css中定义多个属性为一个类
2、修改JS中元素的className为指定类
添加
1、创建一个新的空元素
var a = document.createElement("a");
2、设置密钥属性