DOM学识梳理
DOM
我们知道,JavaScript是由ECMAScript + DOM + BOM组成的。ECMAScript是JS中的一些语法,而BOM主要是浏览器对象(window)对象的一些相关知识的集合。而DOM,则是文档对象相关的知识的集合。
我们知道,HTML和JS之间的交互是通过事件实现的。而DOM是针对HTML(XML)文档的一个API。因此,如果我们想实现与用户的交互,那么就需要使用DOM提供的API,获取HTML元素,然后在该元素上绑定相应的事件,实现与用户的交互。所以,对DOM的理解和掌握就显得相当重要。
本文章主要基于《JavaScript高级程序涉及(三)》中的DOM相关章节,对DOM的主要知识作出一个梳理,并穿插我个人的一些理解。
节点层次
写过HTML代码的地球人应该都知道,我们需要给每一个元素添加缩进,然后在书写相关的HTMl标签和内容,最后显示在网页上。因此这种嵌套的HTML代码和内容就构成了节点层次。
对ECMAScript理解的地球人应该都知道,JS中的每一个对象都是基于一个引用类型创建的,而引用类型可以是JS原生提供的引用类型(Array、Function、RegExp、Object等),也可以是自定义的引用类型(通过new关键字调用引用类型(也可以叫构造函数))。而所有对象都是Object的实例对象,都可以继承Object.prototype上的属性和方法
而在DOM中,也同样有这样类似的机制。在DOM中,最顶层的类型是Node类型,其他所有节点都可以继承Node类型下的属性和方法。而Node类型实际上就相当于JS中的Object构造函数。
既然如此,那就线看看Node类型下有哪些属性和方法
Node类型
-
属性(在某个特定的节点通过继承的方式调用以下属性)
- nodeType
- nodeName
- nodeValue
- ·············
- childNodes(指针,指向NodeList对象)
- parentNodes
- nextSibling
- previousSibling
- firstChild
- lastChild
- ownDocument(每个节点都只能属于一个Document节点)
-
方法(在某个特定的节点通过继承的方式调用以下方法)
- ··· 查找节点 ···
- 查找元素的方法位于Document类型中
- ························
- ··· 插入节点 ···
- appendChild(ele)
- insertBefore(ele, target)
- ························
- ··· 删除节点 ···
- removeChild(ele)
- ························
- ··· 替换节点 ···
- replaceChild(ele, target)
- ························
- ··· 复制节点 ···
- cloneNode(boolean) true: 表示深复制, false: 表示浅复制
- ························
- ··· 处理文档节点 ··· 很少用~
- normalize()
Node类型上的属性和方法也就那么多了,再啰嗦一次,所有的其他节点都可以继承Node类型上的属性和方法
Document类型
JS通过Document类型表示文档。document对象是HTMLDocument的一个实例,表示整个HTML页面。同时,document对象也是window对象下的一个属性,因此可以将其作为全局对象来访问。
- 属性
- document.documentElement (表示HTML元素),同时可以通过document.childNodes[1]获取HTML元素
- document.body (表示body元素)
- document.head (表示head元素)
- document.compatMode (表示浏览器采用哪种渲染方式,'CSS1Compat'表示标准模式, 'BackCompat'表示混杂模式)
- document.charset (表示文档中实际使用的字符集,也可用来指定新字符集)
- document.dataset (表示通过dataset访问自定义属性,如document.dataset.myname)
- document.docType (表示 元素), 存在浏览器兼容性问题
- document.title (表示 < title > 元素)
- ··· 网页请求 ···
- document.URL (获取URL地址)
- document.domain (获取URL中的域名,pathname)
- document.attributes (获取某个节点的属性,返回NamedNodeMap对象,与NodeList类似)
- 方法
- ··· 查找元素 ···
- document.getElementById(id) 返回该元素
- document.getElementsByTagName(classname) 返回包含零个或多个元素的HTMLCollection对象,与NodeList对象相似
- document.getElementsByName(ele)返回带有给定name属性的元素,同样返回HTMLCollection对象
- document.getElementsByClassName(className) 返回所有匹配的NodeList对象 (可在Document类型、Element类型上调用该方法)
- document.querySelector(selector) selector表示CSS选择符 返回与该模式匹配的第一个元素,如果没有找到,返回null (Document类型, DocumentFragment类型, Element类型都可以调用此方法)
- document.querySelectorAll(selector) selector表示CSS选择符 返回一个匹配成功的NodeList对象 (Document类型, DocumentFragment类型, Element类型都可以调用此方法)
- ··· 创建元素 ···
- document.createElement() (创建好的元素处于游离状态,需要通过appendChild插入)
- ··· 创建文本节点 ···
- document.createTextNode() (创建好的元素处于游离状态,需要通过appendChild插入)
- ··· 确定元素大小 ···
- document.getBoundingClientRect()
Element类型
- 属性
- id
- title
- lang
- className
- 方法
- getAttribute(ele) 获取某个属性
- setAttribute(name, value) 设置某个属性
- removeAttribute(ele) 移除某个属性
- getElementsByTagName(ele) 获取标签名为ele的元素
Text类型
- 属性
- nodeValue | data (访问Text节点中的文本)
DocumentFragment类型
用途:离线操作DOM元素,避免DOM节点大量的重排和重绘,造成性能问题
- 方法
- document.createDocumentFragment() (表示创建文档片段)
NodeList对象
理解 NodeList 及其“近亲”NamedNodeMap 和 HTMLCollection,是从整体上透彻理解 DOM 的关键所在。这三个集合都是“动态的”;换句话说,每当文档结构发生变化时,它们都会得到更新。因此,它们始终都会保存着最新、最准确的信息。从本质上说,所有NodeList 对象都是在访问 DOM 文档时实时运行的查询。
元素大小
偏移量(offset dimension)
要想知道某个元素在页面上的偏移量,将这个元素的 offsetLeft 和 offsetTop 与其 offsetParent的相同属性相加,如此循环直至根元素,就可以得到一个基本准确的值。以下两个函数就可以用于分别取得元素的左和上偏移量。
function getElementLeft(element){
var actualLeft = element.offsetLeft;
var current = element.offsetParent;
while (current !== null){
actualLeft += current.offsetLeft;
current = current.offsetParent;
}
return actualLeft;
}
function getElementTop(element){
var actualTop = element.offsetTop;
var current = element.offsetParent;
while (current !== null){
actualTop += current. offsetTop;
current = current.offsetParent;
}
return actualTop;
}
客户区大小(client dimension)
要确定浏览器视口大小,可以使用 document.documentElement 或 document.body(在IE7 之前的版本中)的clientWidth 和 clientHeight。
function getViewport(){
if (document.compatMode == "BackCompat"){
return {
width: document.body.clientWidth,
height: document.body.clientHeight
};
} else {
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight
};
}
}
滚动大小(scroll dimension)
·················
确定元素大小
document.getBoundingClientRect()方法, 返回一个矩形对象。包含4个属性:left、top、right和bottom。这些属性给出了元素在页面中相对于视口的位置。