(84)Wangdao.com第十八天_JavaScript 文档对象模型 DOM
文档对象模型 DOM
DOM 是 JavaScript 操作网页的接口,
全称为“文档对象模型”(Document Object Model)。
作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)
浏览器会根据 DOM 模型,将结构化文档(比如 HTML 和 XML)解析成一系列的节点,
再由这些节点组成一个树状结构(DOM Tree)。所有的节点和最终的树状结构,都有规范的对外接口。
DOM 只是一个接口规范,可以用各种语言实现。
- 节点
- DOM 的最小组成单位叫做节点(node)。
- 文档的树形结构(DOM 树),就是由各种不同类型的节点组成。
- 每个节点可以看作是文档树的一片叶子。
- 节点的类型有七种:
- 文档节点 Document: 整个文档树的顶层节点
- 文档类型节点 DocumentType: doctype标签(比如<!DOCTYPE html>)
- 元素节点 Element: 网页的各种HTML标签(比如<body>、<a>等)
- 属性节点 Attribute: 网页元素的属性(比如class="right")
- 文本节点 Text: 标签之间或标签包含的文本
- 注释节点 Comment: 注释(比如<!-- 页首部分 -->)
- 文档片段节点 DocumentFragment: 文档的片段
- 节点的类型有七种:
- 浏览器原生提供 document 节点,代表整个文档
- 文档 document 的第一层只有一个节点,就是 HTML 网页的第一个标签 <html>,
- 它构成了树结构的根节点(root node),其他 HTML 标签节点都是它的下级节点。
- 文档 document 的第一层只有一个节点,就是 HTML 网页的第一个标签 <html>,
- 根节点,其他节点都有三种层级关系
- 父节点关系(parentNode):直接的那个上级节点
- 子节点关系(childNodes):直接的下级节点
- 同级节点关系(sibling):拥有同一个父节点的节点
- 根节点,其他节点都有三种层级关系
- DOM 提供操作接口,用来获取这三种关系的节点。
- 子节点接口包括 firstChild()(第一个子节点)和 lastChild()(最后一个子节点)等属性
- 同级节点接口包括 nextSibling()(紧邻在后的那个同级节点)和 previousSibling()(紧邻在前的那个同级节点)属性
- DOM 提供操作接口,用来获取这三种关系的节点。
- 有 DOM 节点对象都继承了 Node 接口,拥有一些共同的属性和方法。这是 DOM 操作的基础
- 属性
- Node.prototype.nodeType
- 返回一个整数值,表示节点的类型
document.nodeType // 9
document.nodeType === Node.DOCUMENT_NODE // true
文档节点的nodeType
属性等于 常量Node.DOCUMENT_NODE
- Node 对象定义了几个常量,对应这些类型值
- 元素节点(element):1 对应常量 Node.ELEMENT_NODE
- 属性节点(attr):2 对应常量 Node.ATTRIBUTE_NODE
- 文本节点(text):3 对应常量 Node.TEXT_NODE
- 注释节点(Comment):8 对应常量 Node.COMMENT_NODE
- 文档节点(document):9 对应常量 Node.DOCUMENT_NODE
- 文档类型节点(DocumentType):10 对应常量 Node.DOCUMENT_TYPE_NODE
- 文档片断节点(DocumentFragment):11 对应常量 Node.DOCUMENT_FRAGMENT_NODE
var node = document.documentElement.firstChild;
if (node.nodeType === Node.ELEMENT_NODE) { // 确定节点类型时,使用nodeType
属性是常用方法
console.log('该节点是元素节点');
}
- 返回一个整数值,表示节点的类型
- Node.prototype.nodeName
- 返回节点的名称
- 不同节点的 nodeName 属性值如下
- 元素节点(element):大写的标签名
- 属性节点(attr):小写的属性的名称
- 文本节点(text):#text
- 注释节点(Comment):#comment
- 文档节点(document):#document
- 文档类型节点(DocumentType):文档的类型
- 文档片断节点(DocumentFragment):#document-fragment
// HTML 代码如下
// <div id="d1">hello world</div> var div = document.getElementById('d1');
console.log(div.nodeName); // "DIV"
- Node.prototype.nodeValue
- 返回一个字符串,表示当前节点本身的文本值,该属性可读写。
- 只有文本节点(text)和注释节点(comment)有文本值,因此这两类节点的 nodeValue 可以返回结果,其他类型的节点一律返回 null。
- 同样的,也只有这两类节点可以设置 nodeValue 属性的值,其他类型的节点设置无效
- Node.prototype.nodeType
- 属性
- Node.prototype.textContent
- 返回当前节点和它的所有后代节点的文本内容
// HTML 代码为
// <div id="divA">This is <span>some</span> text</div> document.getElementById('divA').textContent; // This is some text
- 自动忽略当前节点内部的 HTML 标签,返回所有文本内容
- 自动对 HTML 标签转义。这很适合用于用户提供的内容
document.getElementById('foo').textContent = '<p>GoodBye!</p>'; // 会将
<p>
标签解释为文本,而不会当作标签处理。
- 如果要读取整个文档的内容,可以使用 document.documentElement.textContent
- 返回当前节点和它的所有后代节点的文本内容
- Node.prototype.textContent
- Node.prototype.baseURI
- 返回一个字符串,表示当前网页的绝对路径
- 浏览器根据这个属性,计算网页上的相对路径的 URL。
// 当前网页的网址为
// http://www.example.com/index.html
document.baseURI // "http://www.example.com/index.html"
- 该属性为只读
- 如果无法读到网页的 URL,
baseURI
属性返回null
。 - 该属性的值一般由当前网址的 URL(即
window.location
属性)决定,<base href="http://www.example.com/page.html">
但是可以使用 HTML 的
<base>
标签,改变该属性的值
- Node.prototype.baseURI
- Node.prototype.ownerDocument
- 返回当前节点所在的顶层文档对象,即 document 对象
var d = p.ownerDocument;
d === document // true // document对象本身的ownerDocument属性,返回null
- 返回当前节点所在的顶层文档对象,即 document 对象
- Node.prototype.ownerDocument
- Node.prototype.nextSibling
- 返回紧跟在当前节点后面的第一个同级节点。
- 如果当前节点后面没有同级节点,则返回 null
- 注意,该属性还包括文本节点和注释节点(
<!-- comment -->
)。- 因此如果当前节点后面有空格,该属性会返回一个文本节点,内容为空格
- 可以用来遍历所有子节点
var el = document.getElementById('div1').firstChild; while (el !== null) {
console.log(el.nodeName);
el = el.nextSibling;
}
- Node.prototype.nextSibling
- Node.prototype.previousSibling
- 返回当前节点前面的、距离最近的一个同级节点
- 如果当前节点前面没有同级节点,则返回 null
- 注意,该属性还包括文本节点和注释节点。
- 因此如果当前节点前面有空格,该属性会返回一个文本节点,内容为空格
- Node.prototype.previousSibling
- Node.prototype.parentNode
- 返回当前节点的父节点。
- 对于一个节点来说,它的父节点只可能是三种类型:
- 元素节点(element)
- 文档节点(document)
- 文档片段节点(documentfragment)
- 利用 node.parentNode 属性 将node节点从文档里面移除
if (node.parentNode) {
node.parentNode.removeChild(node);
}
- 文档节点(document)和文档片段节点(documentfragment)的父节点都是null
- 对于那些生成后还没插入 DOM 树的节点,父节点也是 null
- Node.prototype.parentNode
- Node.prototype.parentElement
- 返回当前节点的父元素节点
- 如果当前节点没有父节点,或者父节点类型不是元素节点,则返回 null
if (node.parentElement) {
node.parentElement.style.color = 'red'; // 父元素节点的样式设定了红色
}
- Node.prototype.parentElement
- Node.prototype.firstChild Node.prototype.lastChild
- 返回当前节点的 第一个子节点 / 最后一个子节点
- 如果当前节点没有子节点,则返回 null
- Node.prototype.firstChild Node.prototype.lastChild
- Node.prototype.childNodes
- 返回一个类似数组的对象(NodeList 集合),成员包括当前节点的所有子节点
var children = document.querySelector('ul').childNodes;
// 上面代码中,children 就是 ul 元素的所有子节点。 // 使用该属性,可以遍历某个节点的所有子节点。var div = document.getElementById('div1');
var children = div.childNodes;for (var i = 0; i < children.length; i++) {
// ...
}
- 文档节点(document)就有两个子节点:文档类型节点(docType)和 HTML 根元素节点
var children = document.childNodes;
for (var i = 0; i < children.length; i++) {
console.log(children[i].nodeType);
}
//
//
// 上面代码中,文档节点的第一个子节点的类型是10(即文档类型节点),第二个子节点的类型是1(即元素节点)。
- 注意:
- 除了元素节点,childNodes 属性的返回值还包括文本节点和注释节点。
- 如果当前节点不包括任何子节点,则返回一个空的 NodeList 集合。
- 由于 NodeList 对象是一个动态集合,一旦子节点发生变化,立刻会反映在返回结果之中。
- 返回一个类似数组的对象(NodeList 集合),成员包括当前节点的所有子节点
- Node.prototype.childNodes
- Node.prototype.isConnected
- 表示当前节点是否在文档之中,返回一个布尔值
var test = document.createElement('p');
test.isConnected; // false document.body.appendChild(test);
test.isConnected; // true脚本生成的节点,没有插入文档之前,isConnected 属性返回 false,插入之后返回 true
- 表示当前节点是否在文档之中,返回一个布尔值
- Node.prototype.isConnected
- 方法
- Node.prototype.appendChild()
- 接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点。
- 该方法的返回值就是插入文档的子节点。
- 如果参数节点是 DOM 已经存在的节点
- appendChild方法会将其从原来的位置,移动到新位置
var element = document.createElement('div').appendChild(document.createElement('b'));
上面代码的返回值是<b></b>,而不是<div></div>
- 如果 appendChild 方法的参数是 DocumentFragment 节点
- 那么插入的是 DocumentFragment 的所有子节点,而不是 DocumentFragment 节点本身。
- 返回值是一个空的 DocumentFragment 节点
- Node.prototype.hasChildNodes()
- 返回一个布尔值,表示当前节点是否有子节点
var foo = document.getElementById('foo'); if (foo.hasChildNodes()) { // 如果foo节点有子节点,就移除第一个子节点
foo.removeChild(foo.childNodes[0]);
}
- 子节点包括所有类型的节点
- 并不仅仅是元素节点
- 哪怕节点只包含一个空格,hasChildNodes 方法也会返回 true
- 返回一个布尔值,表示当前节点是否有子节点
- Node.prototype.cloneNode()
- 用于克隆一个节点。
- 它接受一个布尔值作为参数,表示是否同时克隆子节点。
- 它的返回值是一个克隆出来的新节点
- 注意:
- 克隆一个节点,会拷贝该节点的所有属性,但是会丧失 addEventListener方法 和 on-属性(即node.onclick = fn)
- 该方法返回的节点不在文档之中,即没有任何父节点,必须使用诸如 Node.appendChild() 这样的方法添加到文档之中
- 克隆一个节点之后,DOM 有可能出现两个有相同id属性(即id="xxx")的网页元素,这时应该修改其中一个元素的id属性。
- 如果原节点有name属性,可能也需要修改
- Node.prototype.insertBefore()
- 用于将某个节点插入父节点内部的指定位置
var insertedNode = parentNode.insertBefore(newNode, referenceNode);
- 第一个参数是所要插入的节点 newNode
- 第二个参数是父节点 parentNode 内部的一个子节点 referenceNode
- newNode 将插在 referenceNode 这个子节点的前面
- 返回值是插入的新节点 newNode
- 如果 insertBefore() 方法的第二个参数为 null,则新节点将插在当前节点内部的最后位置,即变成最后一个子节点
var p = document.createElement('p');
document.body.insertBefore(p, null); //p
将成为document.body
的最后一个子节点
- 注意:
- 如果所要插入的节点是当前 DOM 现有的节点,则该节点将从原有的位置移除,插入新的位置。
- 由于不存在 insertAfter 方法,如果新节点要插在父节点的某个子节点后面,可以用 insertBefore 方法结合 nextSibling 属性模拟
parent.insertBefore(s1, s2.nextSibling);
如果要将 s1 插在 s2 的后面,则插在 s2 后面一个节点的前面即可
- 如果要插入的节点是 DocumentFragment 类型,那么插入的将是 DocumentFragment 的所有子节点,而不是 DocumentFragment 节点本身。返回值将是一个空的 DocumentFragment 节点
- 用于将某个节点插入父节点内部的指定位置
- Node.prototype.removeChild()
- 接受一个子节点作为参数,用于从当前节点移除该子节点。
- 返回值是移除的子节点。
var divA = document.getElementById('A');
divA.parentNode.removeChild(divA); // 移除了divA
节点,这个方法是在 divA 的父节点上 调用的,不是在 divA 上调用的
- 被移除的节点依然存在于内存之中,但不再是 DOM 的一部分。
- 所以,一个节点移除以后,依然可以使用它,比如插入到另一个节点下面。
- 如果参数节点不是当前节点的子节点,removeChild 方法将报错。
- 移除当前节点的所有子节点
var element = document.getElementById('top');
while (element.firstChild) { // 确定当前元素还有子节点
element.removeChild(element.firstChild);
}
- 移除当前节点的所有子节点
- Node.prototype.replaceChild()
- 用于将一个新的节点,替换当前节点的某一个子节点
var replacedNode = parentNode.replaceChild(newChild, oldChild);
- 第一个参数 newChild 是用来替换的新节点
- 第二个参数 oldChild 是将要替换走的子节点。返回值是替换走的那个节点 oldChild
var divA = document.getElementById('divA');
var newSpan = document.createElement('span');
newSpan.textContent = 'Hello World!';
divA.parentNode.replaceChild(newSpan, divA);将指定节点 divA 替换走
- 用于将一个新的节点,替换当前节点的某一个子节点
- Node.prototype.contains()
- 返回一个布尔值,表示参数节点是否满足以下三个条件之一
- 参数节点为当前节点
- 参数节点为当前节点
- 参数节点为当前节点
document.body.contains(node); // 检查参数节点node,是否包含在当前文档之中
- 返回一个布尔值,表示参数节点是否满足以下三个条件之一
- Node.prototype.compareDocumentPosition()
- 用法与contains方法完全一致,返回一个七个比特位的二进制值,表示参数节点与当前节点的关系
// HTML 代码如下
// <div id="mydiv">
// <form><input id="test" /></form>
// </div> var div = document.getElementById('mydiv');
var input = document.getElementById('test'); div.compareDocumentPosition(input); //
input.compareDocumentPosition(div); //
- 用法与contains方法完全一致,返回一个七个比特位的二进制值,表示参数节点与当前节点的关系
- Node.prototype.isEqualNode() Node.prototype.isSameNode()
- isEqualNode() 方法返回一个布尔值,用于检查两个节点是否相等
- 所谓相等的节点,指的是
- 两个节点的类型相同、属性相同、子节点相同。
var p1 = document.createElement('p');
var p2 = document.createElement('p'); p1.isEqualNode(p2) // true
- 两个节点的类型相同、属性相同、子节点相同。
- isSameNode() 方法返回一个布尔值,表示两个节点是否为同一个节点。
var p1 = document.createElement('p');
var p2 = document.createElement('p'); p1.isSameNode(p2); // false
p1.isSameNode(p1); // true
- Node.prototype.normalize()
- 用于清理当前节点内部的所有文本节点(text)
- 它会去除空的文本节点,
- 并且将毗邻的文本节点合并成一个
- 也就是说不存在空的文本节点,以及毗邻的文本节点。
var wrapper = document.createElement('div'); wrapper.appendChild(document.createTextNode('Part 1 '));
wrapper.appendChild(document.createTextNode('Part 2 ')); wrapper.childNodes.length; //
wrapper.normalize();
wrapper.childNodes.length; //使用
normalize
方法之后,两个文本子节点被合并成一个。。。该方法是Text.splitText
的逆方法,可以查看《Text 节点对象》一章,了解更多内容。
- 用于清理当前节点内部的所有文本节点(text)
- Node.prototype.getRootNode()
- 返回当前节点所在文档的根节点,与 ownerDocument属性 的作用相同
- Node.prototype.appendChild()
- 方法
(84)Wangdao.com第十八天_JavaScript 文档对象模型 DOM的更多相关文章
- (84)Wangdao.com第十八天_JavaScript Promise 对象
Promise 对象 是 JavaScript 的异步操作解决方案,为异步操作提供统一接口. 目前 JavaScript 原生支持 Promise 对象 它起到代理作用(proxy),充当异步操作与回 ...
- 文档对象模型 DOM
1 DOM概述 1.1 什么是DOM 文档对象模型 Document Object Model 文档对象模型 是表示和操作 HTML和XML文档内容的基础API 文档对象模型,是W3C组织推荐的处理可 ...
- JavaScript文档对象模型(DOM)——DOM核心操作
文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言(HTML或XML)的标准编程接口. W3C已经定义了一系列DOM接口,通过这些DOM接口可 ...
- (85)Wangdao.com第十八天_JavaScript NodeList 接口,HTMLCollection 接口
NodeList 接口 HTMLCollection 接口 节点都是单个对象,有时需要一种数据结构,能够容纳多个节点 DOM 提供两种节点集合,用于容纳多个节点:NodeList 和 H ...
- 文档对象模型-DOM(二)
从NodeList中选择元素 方法一:item()方法,用于返回其中的单一节点,需要在方法的参数中指定所需元素的索引编号. 当其中没有任何元素时,执行代码是对资源的浪费.因此程序员会在执行代码之前,先 ...
- 文档对象模型-DOM(一)
首先看一下DOM树结构: 每个节点都是一个对象,拥有方法和属性. 脚本可以访问以及更新DOM树(不是源代码). 针对DOM树的修改都会反映到浏览器. 访问并更新DOM树需要两个步骤: 一.定位到与 ...
- DOM(文档对象模型)
1.定义: DOM是Document Object Model文档对象模型的缩写.是针对HTML和XML文档的一个API,通过DOM可以去改变文档. 例如:我们有一段HTML,那么如何访问第二层第一个 ...
- 文档对象模型(DOM)中的结点属性
在文档对象模型中,每个结点都是一个对象.DOM结点有三个重要的属性:nodeName .nodeValue和nodeType,分别表示结点名称.结点的值和结点的类型 一.nodeName,结点名称,只 ...
- 文档对象模型(DOM)
文档对象模型(DOM) DOM可以将任何HTML或XML文档描绘成一个由多层节点构成的结构.节点分为几种不同的类型:文档型节点.元素节点.特性节点.注释节点等共有12种节点类型.DOM1级定义了 ...
随机推荐
- 分布式监控工具Ganglia 介绍 与 集群部署.
如果你目的很明确就是冲着标题来的,不爱看我唠叨,请直接进入第二个分割线之后的内容. 其实之前就是有做Swift监控平台的打算的,但是因为没什么硬性需求么,也不要紧的,就一直搁置了.最近实验室来了个大二 ...
- linux中Shell标准输出错误 >/dev/null 2>&1 分析【转】
Shell中可能经常能看到:>/dev/null 2>&1 eg:sudo kill -9 `ps -elf |grep -v grep|grep $1|awk '{print ...
- Python学习一|anaconda的安装问题以及Python语言的特点
安装时遇到的问题 安装anaconda3.0到D盘之后,配置好两个环境变量:D:\anaconda和D:\anaconda\Scripts.发现在命令行中执行python指令可以,但conda指令却是 ...
- 阿里云RDS的mysql数据库占用空间超过90%的处理
阿里云RDS数据库最大支持2T,目前已经占用了90%,如果进行分库或者迁移比较麻烦,思路是找出占用空间过大的日志或不重要的文件进行删除操作 查询所有数据库占用磁盘空间大小的SQL语句: show bi ...
- C# 特性(Attribute)详细介绍
1.什么是Atrribute 首先,我们肯定Attribute是一个类,下面是msdn文档对它的描述:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注 ...
- 【转】使用import scope解决maven继承(单)问题
http://blog.csdn.net/mn960mn/article/details/50894022 测试环境 maven 3.3.9 想必大家在做SpringBoot应用的时候,都会有如下代码 ...
- wpf 用户自定义事件传参
//自定义传参 ,对外联系的参数 public class ImageZoomChangedEventArgs : RoutedEventArgs { /// <summary> /// ...
- java 异常匹配
抛出异常的时候,异常处理系统会安装代码书写顺序找出"最近"的处理程序. 找到匹配的程序后,它就认为异常将得到清理,然后就不再继续查找. 查找的时候并不要求抛出的异常同处理程序的异常 ...
- 利用MYSQL的加密解密办法应对三级安全等级保护
-- 创建测试表 drop table if EXISTS t_passwd_2; create table t_passwd_2(pass1 varchar(64)); -- 对身份证号加密inse ...
- HDU - 1525
题意:给你两个数,a,b,有两个人轮流进行一次操作, 每次操作可以将大的数减去k倍的小的数,最后不能操作的人输了,问你谁赢了. 思路:我们可以用辗转相除法求出对于每一个状态可以改变几次,这样问题就变成 ...