一、DOM概述
DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型” (Document Object Model)。它的作用是将网页转为一个JavaScript 对象,从而可以用脚本进行各种操作(比如对元素增删内容)
浏览器会根据 DOM 模型,将结构化文档HTML解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree)。所有的节点和最终的树状结构,都有规范的对外接口
DOM 只是一个接口规范,可以用各种语言实现。所以严格地说,DOM 不是 JavaScript 语法的一部分,但是 DOM 操作是 JavaScript最常见的任务,离开了 DOM,JavaScript 就无法控制网页。另一方面,JavaScript 也是最常用于 DOM 操作的语言
1、节点
DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子
节点的类型有七种
- Document:整个文档树的顶层节点
- DocumentType:doctype标签
- Element:网页的各种HTML标签
- Attribute:网页元素的属性(比如class=“right”)
- Text:标签之间或标签包含的文本
- Comment:注释
- DocumentFragment:文档的片段
2、节点树
一个文档的所有节点,按照所在的层级,可以抽象成一种树状结构。这种树状结构就是 DOM 树。它有一个顶层节点,下一层都是顶层节点的子节点,然后子节点又有自己的子节点,就这样层层衍生出一个金字塔结构,倒过来就像一棵树
浏览器原生提供document节点,代表整个文档
除了根节点,其他节点都有三种层级关系
- 父节点关系(parentNode):直接的那个上级节点
- 子节点关系(childNodes):直接的下级节点
- 同级节点关系(sibling):拥有同一个父节点的节点
3、Node.nodeType属性
不同节点的nodeType属性值和对应的常量如下
- 文档节点(document):9,对应常量
- Node.DOCUMENT_NODE
- 元素节点(element):1,对应常量Node.ELEMENT_NODE
- 属性节点(attr):2,对应常量Node.ATTRIBUTE_NODE
- 文本节点(text):3,对应常量Node.TEXT_NODE
- 文档片断节点(DocumentFragment):11,对应常量Node.DOCUMENT_FRAGMENT_NODE
document.nodeType // 9
document.nodeType === Node.DOCUMENT_NODE //true
二、document对象_方法/获取元素
1、document.getElementsByTagName()
document.getElementsByTagName
方法搜索 HTML 标签名,返回符合条件的元素。它的返回值是一个类似数组对象( HTMLCollection
实例),可以实时反映 HTML 文档的变化。如果没有任何匹配的元素,就返回一个空集
var paras = document.getElementsByTagName('p');
如果传入 * ,就可以返回文档中所有 HTML 元素
var allElements = document.getElementsByTagName('*');
2、document.getElementsByClassName()
document.getElementsByClassName
方法返回一个类似数组的对象( HTMLCollection
实例),包括了所有 class
名字符合指定条件的元素,元素的变化实时反映在返回结果中
var elements = document.getElementsByClassName(names);
由于 class
是保留字,所以 JavaScript 一律使用 className
表示 CSS 的 class
参数可以是多个 class
,它们之间使用空格分隔
var elements = document.getElementsByClassName('foo bar');
3、document.getElementsByName()
document.getElementsByName
方法用于选择拥有 name
属性的 HTML 元素(比如 <form>
、 <radio>
、 <img>
等),返回一个类似数组的的对象( NodeList
实例),因为 name
属性相同的元素可能不止一个
// 表单为 <form name="itbaizhan"></form>
var forms = document.getElementsByName('itbaizhan');
4、document.getElementById()
document.getElementById
方法返回匹配指定 id
属性的元素节点。如果没有发现匹配的节点,则返回 null
var elem = document.getElementById('para1');
注意,该方法的参数是大小写敏感的。比如,如果某个节点的 id
属性是 main
,那么 document.getElementById('Main')
将返回 null
5、document.querySelector()
document.querySelector
方法接受一个 CSS 选择器作为参数,返回匹配该选择器的元素节点。如果有多个节点满足匹配条件,则返回第一个匹配的节点。如果没有发现匹配的节点,则返回 null
var el1 = document.querySelector('.myclass');
6、document.querySelectorAll()
document.querySelectorAll
方法与 querySelector
用法类似,区别是返回一个NodeList
对象,包含所有匹配给定选择器的节点
var elementList = document.querySelectorAll('.myclass');
三、document对象_方法/创建元素
1、document.createElement()
document.createElement
方法用来生成元素节点,并返回该节点
var newDiv = document.createElement('div');
2、document.createTextNode()
document.createTextNode
方法用来生成文本节点( Text
实例),并返回该节点。它的参数是文本节点的内容
var newDiv = document.createElement('div');
var newContent =document.createTextNode('Hello');
newDiv.appendChild(newContent);
3、document.createAttribute()
document.createAttribute
方法生成一个新的属性节点( Attr
实例),并返回它
var attribute = document.createAttribute(name);
var root = document.getElementById('root');
var it = document.createAttribute('itbaizhan');
it.value = 'it';
root.setAttributeNode(it);
四、Element对象_属性
Element对象对应网页的 HTML 元素。每一个 HTML 元素,在DOM 树上都会转化成一个Element节点对象(以下简称元素节点)
1、Element.id
Element.id
属性返回指定元素的 id
属性,该属性可读写
// HTML 代码为 <p id="foo">
var p = document.querySelector('p');
p.id // "foo"
2、Element.className
className
属性用来读写当前元素节点的 class
属性。它的值是一个字符串,每个 class
之间用空格分割
// HTML 代码 <div class="one two three"
id="myDiv"></div>
var div = document.getElementById('myDiv');
div.className
3、Element.classList
classList
对象有下列方法
add()
:增加一个 classremove()
:移除一个 classcontains()
:检查当前元素是否包含某个 classtoggle()
:将某个 class 移入或移出当前元素
var div = document.getElementById('myDiv');
div.classList.add('myCssClass');
div.classList.add('foo', 'bar');
div.classList.remove('myCssClass');
div.classList.toggle('myCssClass'); // 如果 myCssClass 不存在就加入,否则移除
div.classList.contains('myCssClass'); // 返回 true 或者 false
4、Element.innerHTML
Element.innerHTML
属性返回一个字符串,等同于该元素包含的所有HTML 代码。该属性可读写,常用来设置某个节点的内容。它能改写所有元素节点的内容,包括 <HTML>
和 <body>
元素
el.innerHTML = '';
5、Element.innerText
innerText
和 innerHTML
类似,不同的是 innerText
无法识别元素,会直接渲染成字符串
五、Element获取元素位置
1、Element.clientHeight,Element.clientWidth
Element.clientHeight
属性返回一个整数值,表示元素节点的 CSS 高度(单位像素),只对块级元素生效,对于行内元素返回 0
。如果块级元素没有设置 CSS 高度,则返回实际高度
除了元素本身的高度,它还包括 padding
部分,但是不包括 border
、 margin
。如果有水平滚动条,还要减去水平滚动条的高度。注意,这个值始终是整数,如果是小数会被四舍五入。
Element.clientWidth
属性返回元素节点的 CSS 宽度,同样只对块级元素有效,也是只包括元素本身的宽度和 padding
,如果有垂直滚动条,还要减去垂直滚动条的宽度。
document.documentElement
的 clientHeight
属性,返回当前视口的高度(即浏览器窗口的高度)。 document.body
的高度则是网页的实际高度。
// 视口高度
document.documentElement.clientHeight
// 网页总高度
document.body.clientHeight
2、Element.scrollHeight,Element.scrollWidth
Element.scrollHeight
属性返回一个整数值(小数会四舍五入),表示当前元素的总高度(单位像素),它包括 padding
,但是不包括 border
、 margin
以及水平滚动条的高度(如果有水平滚动条的话)
Element.scrollWidth
属性表示当前元素的总宽度(单位像素),其他地方都与 scrollHeight
属性类似。这两个属性只读
整张网页的总高度可以从 document.documentElement
或 document.body
上读取
// 返回网页的总高度
document.documentElement.scrollHeight
document.body.scrollHeight
3、Element.scrollLeft,Element.scrollTop
Element.scrollLeft
属性表示当前元素的水平滚动条向右侧滚动的像素数量, Element.scrollTop
属性表示当前元素的垂直滚动条向下滚动的像素数量。对于那些没有滚动条的网页元素,这两个属性总是等于0
如果要查看整张网页的水平的和垂直的滚动距离,要从document.documentElement
元素上读取
document.documentElement.scrollLeft
document.documentElement.scrollTop
4、Element.offsetHeight,Element.offsetWidth
Element.offsetHeight
属性返回一个整数,表示元素的 CSS 垂直高度(单位像素),包括元素本身的高度、padding 和 border,以及水平滚动条的高度(如果存在滚动条)。
Element.offsetWidth
属性表示元素的 CSS 水平宽度(单位像素),其他都与 Element.offsetHeight
一致。
这两个属性都是只读属性,只比 Element.clientHeight
和 Element.clientWidth
多了边框的高度或宽度。如果元素的 CSS 设为不可见(比如 display: none;
),则返回 0
5、Element.offsetLeft,Element.offsetTop
Element.offsetLeft
返回当前元素左上角相对于 Element.offsetParent
节点的水平位移, Element.offsetTop
返回垂直位移,单位为像素。通常,这两个值是指相对于父节点的位移
<div class="parent">
<div class="box" id="box"></div>
</div>
.parent{
width: 200px;
height: 200px;
background: red;
position: relative;
left: 50px;
top: 50px;
}
.box{
width: 100px;
height: 100px;
background: yellow;
position: relative;
left: 50px;
top: 50px;
}
var box = document.getElementById("box");
console.log(box.offsetLeft);
console.log(box.offsetTop);