共计 11960 个字符,预计需要花费 30 分钟才能阅读完成。
DOM
DOM 是 JS 操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为一个 JS 对象,从而能够用脚本进行各种操作(比方增删内容)。
• 文档
– 文档示意的就是整个的 HTML 网页文档
• 对象
– 对象示意将网页中的每一个局部都转换为了一个对象。
• 模型
– 应用模型来示意对象之间的关系,这样不便咱们获取对象
文档对象模型(DOM)是网页的编程接口。它给文档(构造树)提供了一个结构化的表述并且定义了一种形式——程序能够对构造树进行拜访,以扭转文档的构造,款式和内容。
DOM 提供了一种表述模式将文档作为一个结构化的节点组以及蕴含属性和办法的对象。从实质上说,它将 web 页面和脚本或编程语言连接起来了。
要扭转页面的某个货色,JS 就须要取得对网页中所有元素进行拜访的入口。这个入口,连同对 HTML 元素进行增加、挪动、扭转或移除的办法和属性,都是通过 DOM 来取得的。
浏览器会依据 DOM 模型,将结构化文档(比方 HTML 和 XML)解析成一系列的节点,再由这些节点组成一个树状构造(DOM Tree)。所有的节点和最终的树状构造,都有标准的对外接口。所以,DOM 能够了解成网页的编程接口。DOM 有本人的国际标准,目前的通用版本是 DOM 3,DOM 4。
严格地说,DOM 不属于 JS,然而操作 DOM 是 JS 最常见的工作,而 JS 也是最罕用于 DOM 操作的语言。DOM 是浏览器厂商提供的 js 操作 html 的 api,不同的浏览器厂商提供的 api 可能不同,所以 dom 存在兼容性问题(少部分)
1. 节点层级
任何 HTML 或 XML 文档都能够用 DOM 示意为一个由节点形成的层级构造。节点分很多类型,每种类型对应着文档中不同的信息和(或)标记,也都有本人不同的个性、数据和办法,而且与其余类型有某种关系。这些关系形成了层级,让标记能够示意为一个以特定节点为根的树形构造。以上面的 HTML 为例:
<html>
<head>
<title>Sample Page</title>
</head>
<body>
<p>Hello World!</p>
</body>
</html>
<img src=”images/image-20210902204641589.png” alt=”image-20210902204641589″ style=”zoom: 33%;” />
其中,document 节点示意每个文档的根节点。在这里,根节点的惟一子节点是 <html> 元素,咱们称之为文档元素(documentElement)。文档元素是文档最外层的元素,所有其余元素都存在于这个元素之内。每个文档只能有一个文档元素。在 HTML 页面中,文档元素始终是 <html> 元素。在 XML 文档中,则没有这样预约义的元素,任何元素都可能成为文档元素。HTML 中的每段标记都能够示意为这个树形构造中的一个节点。元素节点示意 HTML 元素,属性节点示意属性,文档类型节点示意文档类型,正文节点示意正文。DOM 中总共有 12 种节点类型,这些类型都继承一种根本类型。
1.2. 节点
DOM 的最小组成单位叫做节点(node)。文档的树形构造(DOM 树),就是由各种不同类型的节点组成。每个节点能够看作是文档树的一片叶子。
节点的类型有七种:Document、DocumentType、Element、Text、Comment、DocumentFragment。
-
罕用节点
文档节点(document)
整个 HTML 文档 document 对象作为 window 对象的属性存在的,咱们不必获取能够间接应用。
元素节点(Element)
HTML 文档中的 HTML 标签。
属性节点(Attribute)
元素的属性 示意的是标签中的一个一个的属性,这里要留神的是属性节点并非是元素节点的子节点,而是元素节点的一部分。
文本节点(Text)
HTML 标签中的文本内容。
-
其余节点
DocumentType
doctype 标签(比方
<!DOCTYPE html>
)。Comment
正文
DocumentFragment
文档的片段
这七种节点都属于浏览器原生提供的节点对象 (上面要讲的 Node 对象) 的派生对象,具备一些独特的属性和办法。
1.3. 节点树
一个文档的所有节点,依照所在的层级,能够形象成一种树状构造。这种树状构造就是 DOM。
<img src=”images/image-20210902210449715.png” alt=”image-20210902210449715″ style=”zoom:50%;” />
最顶层的节点就是 document
节点,它代表了整个文档。文档外面最高的 HTML 标签,个别是<html>
,它形成树结构的根节点(root node),其余 HTML 标签节点都是它的上级。
除了根节点以外,其余节点对于四周的节点都存在三种关系。
- 父节点关系(parentNode):间接的那个下级节点。
- 子节点关系(childNode):间接的上级节点。
- 同级节点关系(sibling):领有同一父节点的节点。
DOM 提供操作接口,用来获取三种关系的节点。其中,子节点接口包含firstChild
(第一个子节点)和lastChild
(最初一个子节点)等属性,同级节点接口包含nextSibling
(紧邻在后的那个同级节点)和previousSibling
(紧邻在前的那个同级节点)属性。
2.Node 类型
DOM Level 1 形容了名为 Node 的接口,这个接口是所有 DOM 节点类型都必须实现的。Node 接口在 JavaScript 中被实现为 Node 类型,在除 IE 之外的所有浏览器中都能够间接拜访这个类型。在 JavaScript 中,所有节点类型都继承 Node 类型,因而所有类型都共享雷同的根本属性和办法。
2.1. 属性
2.1.1.nodeType
nodeType 属性返回一个整数值,示意节点的类型,罕用节点类型如下
节点类型 | 值 | 对应常量 |
---|---|---|
文档节点(document) | 9 | Node.DOCUMENT_NODE |
元素节点(element) | 1 | Node.ELEMENT_NODE |
属性节点(attr) | 2 | Node.ATTRIBUTE_NODE |
文本节点(text) | 3 | Node.TEXT_NODE |
文档类型节点(DocumentType) | 10 | Node.DOCUMENT_TYPE_NODE |
正文节点(Comment) | 8 | Node.COMMENT_NODE |
文档片断节点(DocumentFragment) | 11 | Node.DOCUMENT_FRAGMENT_NODE |
<script>
console.log(document.nodeType); //9
</script>
2.1.2.nodeName
nodeName 属性返回节点的名称
<div id="d1">hello world</div>
<script>
var div = document.getElementById('d1');
console.log(div.nodeName); //DIV
</script>
2.1.3.nodeValue
nodeValue 属性返回一个字符串,示意以后节点自身的文本值,该属性可读写只有文本节点(text)、正文节点(comment)和属性节点(attr)有文本值.
<div id="d1">hello world</div>
<script>
var div = document.getElementById('d1');
console.log(div.nodeValue); // null
// 读
console.log(div.firstChild.nodeValue); //hello world
// 写
div.firstChild.nodeValue = '123';
</script>
2.1.4.textContent
textContent 属性返回以后节点和它的所有后辈节点的文本内容
<div id="d1">Hello <span>JavaScript</span> DOM</div>
<script>
var div = document.getElementById('d1');
console.log(div.textContent); //Hello JavaScript DOM
</script>
2.1.5.nextSibling 下一个节点
nextSibling 属性返回紧跟在以后节点前面的第一个同级节点。如果以后节点前面没有同级节点,则返回 null
(留神:可能会获取到“空格”或“回车”这样的文本节点)
<div id="d1">hello</div><div id="d2">world</div>
<script>
var div1 = document.getElementById('d1');
var div2 = document.getElementById('d2');
console.log(div1.nextSibling); //<div id="d2">world</div>
console.log(div1.nextSibling === div2); // true
</script>
2.1.6.previousSibling 上一个节点
previousSibling 属性返回以后节点后面的、间隔最近的一个同级节点。如果以后节点后面没有同级节点,则返回 null
<div id="d1">hello</div><div id="d2">world</div>
<script>
var div1 = document.getElementById('d1');
var div2 = document.getElementById('d2');
console.log(div2.previousSibling); //<div id="d1">hello</div>
console.log(div2.previousSibling === div1); // true
</script>
2.1.7.parentNode 返回以后节点的父节点
parentNode 属性返回以后节点的父节点。对于一个节点来说,它的父节点只可能是三种类型:元素节点 (element)、文档节点(document) 和文档片段节点(documentfragment)
<div id="d1">hello world</div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.parentNode); // body
</script>
2.1.8.parentElement
parentElement 属性返回以后节点的父元素节点。如果以后节点没有父节点,或者父节点类型不是元素节点,则返回 null
<div id="d1">hello world</div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.parentElement); // body
// 将父元素节点的背景色彩设置为红色
div1.parentElement.style.backgroundColor = 'red';
</script>
2.1.9.firstChild 和 lastChild
firstChild 属性返回以后节点的第一个子节点,如果以后节点没有子节点,则返回 null,last 则返回最初一个子节点。
<div id="d1">hello world<div> 我是子节点 </div></div>
<div id="d2"><div> 我是子节点 </div></div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.firstChild); // hello world
console.log(div1.lastChild); // <div> 我是子节点 </div>
var div2 = document.getElementById('d2');
console.log(div2.firstChild); // <div> 我是子节点 </div>
</script>
2.1.10.childNodes
childNodes 属性返回一个相似数组的对象(NodeList 汇合),成员包含以后节点的所有子节点
<div id="d1">hello world<div> 我是子节点 </div></div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.childNodes); //NodeList[text, div]
</script>
咱们还能够应用 for 循环来遍历某个节点的所有子节点
var div = document.getElementById('div1');
var children = div.childNodes;
for (var i = 0; i < children.length; i++) {// ...}
2.2. 办法
以下办法为罕用操作节点的办法,其中最罕用的办法是 appendChild(),用于在 childNodes 列表开端增加节点。
留神:以下四个办法都须要父节点对象进行调用!
2.2.1.appendChild
appendChild 办法承受一个节点对象作为参数,将其作为最初一个子节点,插入以后节点。该办法的返回值就是插入文档的子节点。
<script>
// 创立元素节点 p
var p = document.createElement('p');
// 向 p 标签插入内容
p.innerHTML = '我是一个 p 标签';
// 将节点插入到 body 中
document.body.appendChild(p);
</script>
2.2.2.insertBefore()
insertBefore 办法用于将某个节点插入父节点外部的指定地位。
var insertedNode = parentNode.insertBefore(newNode, referenceNode);
insertBefore 办法承受两个参数,第一个参数是所要插入的节点 newNode,第二个参数是父节点 parentNode 外部的一个子节点 referenceNode。newNode 将插在 referenceNode 这个子节点的后面。返回值是插入的新节点 newNode
<div id="parentElement">
<span id="childElement">foo bar</span>
</div>
<script>
// 创立一个新的、一般的 <span> 元素
var sp1 = document.createElement("span");
// 向 span 标签插入内容
sp1.innerHTML = '我是 span 标签'
// 插入节点之前,要取得节点的援用
var sp2 = document.getElementById("childElement");
// 取得父节点的援用
var parentDiv = sp2.parentNode;
// 在 DOM 中在 sp2 之前插入一个新元素
parentDiv.insertBefore(sp1, sp2);
</script>
2.2.3.removeChild()
removeChild 办法承受一个子节点作为参数,用于从以后节点移除该子节点。返回值是移除的子节点。
<div id="d1">
<span id="s1"> 我是 span 标签 </span>
</div>
<script>
var span1 = document.getElementById('s1');
span1.parentNode.removeChild(span1);
</script>
2.2.4.replaceChild()
replaceChild 办法用于将一个新的节点,替换以后节点的某一个子节点。
var replacedNode = parentNode.replaceChild(newChild, oldChild);
replaceChild 办法承受两个参数,第一个参数 newChild 是用来替换的新节点,第二个参数 oldChild 是将要替换走的子节点。返回值是替换走的那个节点 oldChild。
<div id="d1">
<span id="s1"> 我是 span 标签 </span>
</div>
<script>
var span1 = document.getElementById('s1');
// 创立一个新的 div 标签
var div1 = document.createElement("div");
// 向 div 标签插入内容
div1.innerHTML = '我是 div1 标签';
// 节点替换
span1.parentNode.replaceChild(div1, span1);
</script>
2.2.5. 其余办法
cloneNode()
办法返回调用该办法的节点的一个正本.
var dupNode = node.cloneNode(deep);
node
将要被克隆的节点
dupNode
克隆生成的正本节点
deep 可选
是否采纳深度克隆, 如果为 true, 则该节点的所有后辈节点也都会被克隆, 如果为 false, 则只克隆该节点自身。
var p = document.getElementById("para1"),
var p_prime = p.cloneNode(true);
3.Document 类型
Javascript 通过应用 Document 类型示意文档。在浏览器中,document 对象是 HTMLDocument 的一个实例,示意整个 HTML 页面。document 对象是 window 对象的一个属性,因而能够间接调用。HTMLDocument 继承自 Document。
3.1. 属性
documentElement
始终指向 HTML 页面中的 <html> 元素。
body
间接指向 <body> 元素
doctype
拜访 <!DOCTYPE>, 浏览器反对不统一,很少应用
title
获取文档的题目
URL —–>> document.URL
获得残缺的 URL
domain —–>> document.domain
获得域名,并且能够进行设置,在跨域拜访中常常会用到。
referrer —–>> document.referrer
获得链接到以后页面的那个页面的 URL,即起源页面的 URL。
images
获取所有的 img 对象,返回 HTMLCollection 类数组对象
forms
获取所有的 form 对象,返回 HTMLCollection 类数组对象
links
获取文档中所有带 href 属性的元素
3.2.DOM 编程界面
HTML DOM 可能通过 JavaScript 进行拜访(也能够通过其余编程语言)。
在 DOM 中,所有 HTML 元素都被定义为 对象。
编程界面是每个对象的属性和办法。
属性是您可能获取或设置的值(就比方扭转 HTML 元素的内容)。
办法是您可能实现的动作(比方增加或删除 HTML 元素)。
实例
上面的例子扭转了 id=”demo” 的 <p> 元素的内容:
<html>
<body>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = "Hello World!";
</script>
</body>
</html>
在下面的例子中,getElementById 是办法,而 innerHTML 是属性。
getElementById 办法
拜访 HTML 元素最罕用的办法是应用元素的 id。
在下面的例子中,getElementById 办法应用 id=”demo” 来查找元素。
innerHTML 属性
获取元素内容最简略的办法是应用 innerHTML 属性。
innerHTML 属性可用于获取或替换 HTML 元素的内容。
innerHTML 属性可用于获取或扭转任何 HTML 元素,包含 <html> 和 <body>。
3.3. 查找元素
办法 | 形容 |
---|---|
document.getElementById(id) | 通过元素 id 来查找元素 |
document.getElementsByTagName(name) | 通过标签名来查找元素 |
document.getElementsByClassName(name) | 通过类名来查找元素 |
document.querySelector() | 返回文档中匹配指定的 CSS 选择器的第一元素 |
document.querySelectorAll() | document.querySelectorAll() 是 HTML5 中引入的新办法,返回文档中匹配的 CSS 选择器的所有元素节点列表 |
getElementById()
返回匹配指定 id 的一个元素。
<div id="d1"> 我是一个 div 标签 </div>
<script>
// 查找 id 为 d1 的标签
var div = document.getElementById('d1');
console.log(div);
</script>
getElementsByTagName()
返回一个HTMLCollection
(伪数组),蕴含匹配指定标签名的所有元素。
<p> 我是 p 标签 </p>
<p> 我是 p 标签 </p>
<p> 我是 p 标签 </p>
<script>
// 查找所有 p 标签
var p = document.getElementsByTagName('p');
console.log(p);
</script>
getElementsByClassName()
返回一个 HTML 汇合HTMLCollection
(伪数组),蕴含匹配指定类名的所有元素。
<div class="div1"> 我是 div 标签 </div>
<div class="div1"> 我是 div 标签 </div>
<div class="div1"> 我是 div 标签 </div>
<script>
// 查找 class 为 div1 的标签
var div = document.getElementsByClassName('div1');
console.log(div);
</script>
document.querySelector()
返回文档中匹配指定的 CSS 选择器的第一元素
<div id="div1"> 我是一个 div</div>
<div id="div1"> 我是一个 div</div>
<script>
document.querySelector("#div1").innerHTML = "Hello World!";
</script>
document.querySelectorAll()
document.querySelectorAll() 是 HTML5 中引入的新办法,返回文档中匹配的 CSS 选择器的所有元素节点列表
<div class="div1"> 我是一个 div</div>
<div class="div1"> 我是一个 div</div>
<script>
console.log(document.querySelectorAll(".div1"));
var x = document.querySelectorAll(".div1");
x[0].innerHTML = '我是新的 div';
</script>
3.4. 增加元素
document.createElement(element)
创立一个新的 HTML 元素,要与 appendChild() 或 insertBefore()办法联结应用。其中,appendChild() 办法在节点的子节点列表末增加新的子节点。insertBefore() 办法在节点的子节点列表任意地位插入新的节点。
<script>
// 创立元素节点 p
var p = document.createElement('p');
// 向 p 标签插入内容
p.innerHTML = '我是一个 p 标签';
// 将节点插入到 body 中
document.body.appendChild(p);
</script>
3.5. 写入
document.write()
向文档写如文本或 HTML 表达式 或 JavaScript 代码。
<script>
document.write("<p>Hello world!</p>");
document.write("<span>Hello DOM!</span>");
document.write("Hello Weekend!");
</script>
4.Element 类型
Element 对象对应网页的 HTML 元素。每一个 HTML 元素在 DOM 树上都会转化成一个 Element 节点对象。
4.1. 属性
attributes:返回一个与该元素相干的所有属性的汇合。
classList:返回该元素蕴含的 class 属性的汇合。
className:获取或设置指定元素的 class 属性的值。
clientHeight:获取元素外部的高度,蕴含内边距,但不包含程度滚动条、边框和外边距。
clientTop:返回该元素间隔它上边界的高度。
clientLeft:返回该元素间隔它左边界的宽度。
clientWidth:返回该元素它外部的宽度,包含内边距,但不包含垂直滚动条、边框和外边距。
innerHTML:设置或获取 HTML 语法示意的元素的后辈。
tagName:返回以后元素的标签名。
4.2. 罕用办法
办法 | 形容 |
---|---|
element.innerHTML = new html content | 扭转元素的 innerHTML |
element.attribute = value | 批改属性的值 |
element.getAttribute() | 返回元素节点的指定属性值。 |
element.setAttribute(attribute, value) | 设置或扭转 HTML 元素的属性值 |
element.style.property = new style | 扭转 HTML 元素的款式 |
element.innerHTML
属性设置或获取 HTML 语法示意的元素的后辈。
<div id="div1"> 我是一个 div</div>
<script>
var d1 = document.getElementById('div1');
// 获取
console.log(d1.innerHTML);
// 设置
d1.innerHTML = '我是新的内容'
</script>
element.attribute = value
批改曾经存在的属性的值
<div id="div1">123</div>
<script>
var d1 = document.getElementById('div1');
// 间接将曾经存在的属性进行批改
d1.id = 'div2';
</script>
element.getAttribute()
返回元素节点的指定属性值。
<div id="div1"> 我是一个 div</div>
<script>
var div = document.getElementById('div1');
console.log(div.getAttribute('id')); // div1
</script>
element.setAttribute(attribute, value)
把指定属性设置或更改为指定值。
<div id="div1"> 我是一个 div</div>
<script>
var d1 = document.getElementById('div1');
// 设置 div1 的 class 为 divCla
d1.setAttribute('class', 'divCla');
</script>
element.style.property
设置或返回元素的 style 属性。
<div id="div1"> 我是一个 div</div>
<script>
var d1 = document.getElementById('div1');
// 获取 div1 的 style 款式
console.log(d1.style);
// 设置 div1 的 style
d1.style.backgroundColor = 'red';
</script>
其余详见 https://www.w3school.com.cn/j…
https://developer.mozilla.org…
5.Text 类型
Text 节点由 Text 类型示意,蕴含按字面解释的纯文本,也可能蕴含本义后的 HTML 字符,但不含 HTML 代码。
5.1. 属性及办法
文本长度
length
追加文本
appendData(text)
删除文本
deleteData(beginIndex,count)
插入文本
insertData(beginIndex,text)
替换文本
replaceData(beginIndex,count,text)
从 beginIndex 地位将以后文本节点分成两个文本节点
splitText(beginIndex)
创立文本节点,参数为要插入节点中的文本
document.createTextNode(text)
从 beginIndex 开始提取 count 个子字符串
substringData(beginIndex,count)
综合案例
<div id="container"></div>
<script> // 创立文本节点
var textNode = document.createTextNode('Hello World!'); // 获取 container
var div = document.getElementById('container'); // 将文本节点插入 container div.appendChild(textNode); // 替换文本
textNode.replaceData(0,5,'Hi'); // 插入文本
textNode.insertData(0, 'Hello')
</script>