DOM 定义了访问 HTML 和 XML 文档的标准,同时它也是一个编程接口。DOM 早期针对于 XML 后来通过扩展后可用于 HTML,它把页面映射为一个多层节点结构,并提供方法、属性使得程序能够对该结构进行访问及修改,从而改变文档对应节点的样式和内容。javascript
简单来讲,浏览器在显示页面的时候须要解析文档,而脚本语言也须要获取这份文档,可是它们最终须要获取到的信息是不一样的,因此 DOM 至关于一个桥梁,沟通了脚本语言和浏览器。因此当咱们修改这个由 DOM 构建出的对象时,页面也会发生相应的变化。html
若是将一个web页面当作一个文档,因为不一样的浏览器有各自的 DOM 标准,因此浏览器在解析页面的时候会映射出不一样的 DOM 树模型,从而致使在操做、访问页面节点上存在差别。例如IE中全部的DOM对象都是以 COM 对象的形式实现的,因此和其余浏览器实现的DOM对象行为不一样。java
注:SVG、MathML、SMIL都是基于XML的语言,它们都发布了针对了本身的 DOM 标准node
W3C 组织为了防止 Netscape 公司和微软按本身意愿开发致使浏览器兼容困难状况发生。规划了 DOM 标准,Web 浏览器在 DOM 标准出现一段时间后才开始实现它,如今的浏览器的首要目的就是支持 DOM,有了标准就对开发者更加的友好了。web
同时须要注意的是 DOM 不只针对 JavaScript,其余语言也实现了DOM。编程
对象:Document、Node、ElementNode、TextNode、AttributeNode、CommentNode、NodeList跨域
接口:createElement、appendChild、setAttribute等数组
接口分类:浏览器
提供了全部文档类型增删改查操做,经过对象提供的接口修改 DOM 树及其表明的文档。安全
对象:Image、Table、Form、 Input 等
接口:createElement、appendChild、setAttribute等
只提供了HTML增删改查操做,经过将 HTML 类型的封装,来简化和对象对应DOM的访问和操做。
var img = new Image();
img.src = 'xxxx';
img.style.width = '100px';
复制代码
总结:他们都为指定的文档类型提供了对象、属性、方法和事件。只不过核心DOM提供的是文档基本类型的扩展,HTML DOM提供的只是HTML类型的扩展。
DOM树结构由一个个的节点组成,节点又分为不一样的类型,不一样的类型有其特有的行为和特征。每一个节点都有包含着本身的信息和接口等,因为节点和节点间有必定的关系,能够造成了层次关系,最终的体现就是以HTML元素即文档元素为根节点的树状结构。
JavaScript 中全部的节点类型都是继承于Node 类型,因此全部的节点都共享着相同的基本属性和基本方法。
因为关系指针都是可读的,因此 DOM 提供了操做节点的方法。操做节点的时候,节点的信息以及和其余节点的关系也会相应进行更新。
插入节点
替换节点
移除节点
克隆节点
优化文本节点
Element类型用于表现 XML 、HTML元素,提供了对元素标签名 (TagName)、子节点、特性的访问。也是继承于Node类型。同时在HTML中标签名始终以所有大写的形式显示,在XML中标签名和源代码中相同。
if(element.tagName.toLowerCase() == 'div'){
// 这样能够适用 HTML 和 XML 形式。
}
复制代码
获取标签名可使用 ele.tagName 或者是 ele.nodeName ,两者返回的值都是相同的。
HTMLElement类型继承于Element,全部的HTML元素都是由该类型或者其子类型构建。下面的标准特性就是Element特有的特性。他们均可以经过元素访问特定属性进行访问或修改。
div.id = test;
div.id //test;
复制代码
id 文档中的惟一标识符
title 有关元素的附加说明信息,通常会经过提示条显示出来
lang 元素内容的语言代码,不多使用
dir 语言的方向,默认左到右 ‘ltr’ ,能够修改成右到左 ‘rtl’ 。不多使用
className 和元素的 class 特性对应,能够为元素指定 CSS 类。
childNodes和children的区别
childNodes返回元素、文本甚至是注释
children只返回元素,不返回文本。
<div id="outer">
text1
<div>1</div>
<div>2</div>
<div>3</div>
text2
</div>
复制代码
var dom = document.getElementById('outer');
console.log(dom.children)// HTMLCollection(3)
//0: div
//1: div
//2: div
console.log(dom.childNodes)// NodeList(7)
//0: text
//1: div
//2: text
//3: div
//4: text
//5: div
//6: text
复制代码
特性(attribute )
特性是 HTML 元素节点自带的,浏览器在解析 HTML 文档时,会将标准的特性转换成属性,从而使得脚本程序也能够经过属性来访问到这些特性(id、title、class等)。
<div id = 'test'><div>
复制代码
div.id //因为标签id 为test,因此DOM 对象就会有 body.id="test"。
div.id = 'test1';
div.id //test1;修改属性会致使特性修改。
复制代码
自定义特性
除了标准的特性,还存在自定义特性,须要注意的是自定义特性须要加上 data-
的前缀。这是因为若是咱们直接使用了非标准的特性(不加data-),之后标准更新后可能会致使冲突!
<div id = 't' data-test="666"></div>
复制代码
let elem = getElementById('t');
elem.getAttribute('test') // 666,此时添加到DOM的特性中能够访问到
elem.dataset.test //test,能够在dataset中获取到自定义特性
elem.test //undefined,自定义特性不会添加到属性中
复制代码
方法
elem.hasAttribute(name)
— 检查特性是否存在。
elem.getAttribute(name)
— 获取这个特性值。
elem.setAttribute(name, value)
— 设置这个特性值。
elem.removeAttribute(name)
— 移除这个特性。
属性(property )
特殊特征
style
事件处理程序(onclick)
属性 | 特性 | |
---|---|---|
类型 | 任何值,标准的属性具备规范中描述的类型 | 字符串 |
名字 | 名字(name)是大小写敏感的 | 名字(name)是大小写不敏感的 |
在大多数状况下,最好使用 DOM 属性。仅当 DOM 属性没法知足开发需求,而且咱们真的须要特性时,才使用特性,例如:
data-
开头,那么咱们应该使用 dataset
。href
属性一直是一个 完整的 URL,可是咱们想要的是“原始的”值。相似于Node节点之间的关系,只不过当前关系只包含元素没有text节点、注释节点等其余节点。
在浏览器中document是HTMLDocument对象的一个实例,同时HTMLDocument对象是继承自 Document 对象。 实际上docuemnt 表示的是 HTML页面,同时它也是 window 的一个属性,因此能够经过全局对象来访问。经过 document 能够获取到浏览器文档中全部节点的数据(包括方法)、以及能够操做文档。
如下几个信息都是 Document 对象没有的,都和网页请求有关,这些全部的信息都存在 HTTP 头部 ,只不过经过这些属性能够在Javascript中访问到它们。
document.URL:URL格式为 <协议>://<域名>:<端口>/<路径>
document.domain:能够获取到当前页面的域名。域名的设置只能愈来愈松散,即限制条件愈来愈低。
可使用document.domain实现跨域,可是前提是必须是同一个基础域名,且协议和端口都得一致。Javascript 出于对安全的考虑,因此不一样域的页面不能互相操做。
此时若是存在基础域名和端口都相等的URL,url1 为a.test.com
,url2 为 b.test.com
, 此时若是url1中的 home.html页面须要访问到url2 中的about.html页面且操做about.html页面,此时是没法直接操做的。若是须要操做就须要在url1 和 url2 中分别设置document.domain 为 test.com。 此时两个页面同域,因此能够互相访问和修改。
document.referrer: 保存着连接到当前页面的 URL,若是没有来源页面可能为空。
document.tiltle:能够获取或者修改当前页面的标题,页面的标题会在修改后直接更新。
getElementById 会返回第一个 id 为指定值的元素且区分大小写,可是须要注意若是是在 IE8 及更低版本时,不区分大小写。在 IE7 中调用该方法时会把第一个 name属性为该值或者第一个 id 为该值的元素进行返回.
<input name="test" type="text" value="Just Test"></input>
<div id="test"></div>
//document.getElementById('test') 返回input
复制代码
getElementsByTagName() 能够获取到指定节点为该标签的全部子节点。子节点的集合即 HTMLCollection 对象。若是须要查看到文档中全部的元素,能够经过getElementsByTagName(”*“); HTMLCollection 对象有一个nameItem方法,能够返回符合当前 name 为指定值的元素。
getElementsByClassName 方法返回文档中全部指定类名的元素集合,做为 NodeList 对象。同时能够同时查找多个类
var nodeList = document.getElementsByClassName("className1 className2");
复制代码
getElementsByName() 方法可返回带有指定名称的对象的集合
querySelector();返回与该模式匹配的第一个元素,可兼容到CSS2
querySelectorAll();返回与该模式匹配的全部元素,底层相似于对一组元素的快照,而不是不断的动态查询(损耗性能 )
document.anchors:包含文档中全部带那么特性的元素。
document.forms:包含文档中全部的元素,与document.getElementByTagName("form")的到的结果相同。
document.images:包含文档中全部的元素,与document.getElementByTagName("img")的到的结果相同。
document.links:包含文档中全部带href特性的元素。
理解DOM操做的关键,就是理解DOM对性能的影响。DOM操做每每是 JavaScript 程序中开销最大的部分。因为NodeList是”动态的“,因此每次访问它的时候都会进行一次新的查询,最好避免的方法就是少访问和减小 DOM 操做。
-----高程
在操做类名的时候能够经过元素的classList属性对类名进行添加,删除或者替换,其实是直接操做className的语法糖,表明着当前元素的集合,其兼容性如图所示。
得到焦点的办法
var btn = document.getElementsByTagName('button')[0];
btn.focus()
复制代码
获取当前焦点元素
判断当前文档内节点是否有焦点
参考文档:
一、特性和属性(Attributes and properties)
二、《JavaScript 高级程序设计》