DOM简介( Document Object Model 文档对象模型)
W3C
W3C 文档对象模型 (DOM) 是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。
W3C DOM 标准被分为 3 个不同的部分:
核心 DOM - 针对任何结构化文档的标准模型
XML DOM - 针对 XML 文档的标准模型
HTML DOM - 针对 HTML 文档的标准模型
也就是说,DOM包含三个版本(?),对应不同的DOM模型,由于我对XML还不是很了解,这里主要先讨论HTML DOM
关于XML DOM 的W3C文档:XML DOM 教程
什么是 HTML DOM?
引自W3C:
HTML的标准对象模型
HTML 的标准编程接口
W3C 标准
HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。
换言之,HTML DOM 是关于如何获取、修改、添加或删除 HTML 元素的标准
引自MDN:
文档对象模型 (DOM) 是HTML和XML文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容。DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将web页面和脚本或程序语言连接起来。
一个web页面是一个文档。这个文档可以在浏览器窗口或作为HTML源码显示出来。但上述两个情况中都是同一份文档。文档对象模型(DOM)提供了对同一份文档的另一种表现,存储和操作的方式。 DOM是web页面的完全的面向对象表述,它能够使用如 JavaScript等脚本语言进行修改。
我们之所以能够对Web页面进行添加、删除、更新、操控元素等等活动,就是因为这个DOM才得以实现。它定义了一套对象(方法)规则,使得JavaScript可以根据这些规则来进行编程。更像是一个文档API
DOM 节点(Node)
根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:
整个文档是一个文档节点
每个HTML元素是元素节点
HTML元素内的文本是文本节点
每个HTML属性是属性节点
注释是注释节点
节点树
HTML DOM 将 HTML 文档视作树结构。这种结构被称为节点树:
Temperature Conversion
这也被称为W3C DOM 1级核心
W3C的DOM Level 1 Core是用于更改文档内容树的强大对象模型。所有主流浏览器都支持Mozilla Firefox和Microsoft Internet Explorer。它是网络上脚本编写的强大基础。
怎么称呼这些元素?
例:
DOM 教程DOM 第一课
Hello world!
节点没有父节点;它是根节点
文本节点 "Hello world!" 的父节点是
节点
且
节点拥有两个子节点:
和 节点 节点也拥有一个子节点:文本节点 "DOM 教程"和
节点是同胞节点,同时也是
的子节点并且
元素是 元素的首个子节点
元素是
元素的最后一个子节点DOM 处理中的常见错误是希望元素节点包含文本。
在本例中:
DOM 教程,元素节点 ,包含值为 "DOM 教程" 的文本节点。HTML DOM
首先记住这个:
在 HTML DOM (文档对象模型)中,每个部分都是节点:
文档本身是文档节点
所有HTML元素是元素节点
所有 HTML 属性是属性节点
HTML元素内的文本是文本节点
注释是注释节点
DOM Document
每个载入浏览器的 HTML 文档都会成为 Document 对象。
Document对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。
提示:Document 对象是 Window 对象的一部分,可通过 window.document 属性对其进行访问。
document.URL
URL 属性可返回当前文档的 URL。
比如在现在的窗口下,控制台输入:
alert(document.URL)
document.getElementById()
这个大家都很熟悉了,getElementById() 方法可返回对拥有指定 ID 的第一个对象的引用。
W3C还定义了一个工具函数:getElementById() 是一个重要的方法,在 DOM 程序设计中,它的使用非常常见。我们为您定义了一个工具函数,这样您就可以通过一个较短的名字来使用 getElementById() 方法了:
function id(x) {
if (typeof x == "string") return document.getElementById(x);
return x;
}
// 上面这个函数接受元素 ID 作为它们的参数。使用前编写 x = id(x) 就可以了。
document.getElementsByName()
getElementsByName() 方法可返回带有指定名称的对象的集合。
该方法与 getElementById() 方法相似,但是它查询元素的 name 属性,而不是 id 属性。
另外,因为一个文档中的 name 属性可能不唯一(如 HTML 表单中的单选按钮通常具有相同的 name 属性),所有 getElementsByName() 方法返回的是元素的数组,而不是一个元素。
由于这个方法返回的是一个数组,不是具体的元素,所以必须注意这点:
var inputA = document.getElementsByName("myinput")[0]; // [0]表示获得的所有input元素中第一个
var inputB = document.getElementById("ID"); // ID取值则很精确,因为ID的特殊性
var iA = inputA.attributes; // 元素自带对象,内含该元素所有属性(以键值对存在)
alert(iA.length); // 3
alert(iA[0].name+" : "+iA[0].value); // "type : text"
var iB = inputB.attributes;
alert(iB.length); // 4
alert(iB[0].name+" : "+iB[0].value); // "type : button"
document.getElementsByTagName()
注意要和上面的区分,TagName指的是标签名
getElementsByTagName() 方法可返回带有指定标签名的对象的集合,返回元素的顺序是它们在文档中的顺序。
如果把特殊字符串 "*" 传递给 getElementsByTagName() 方法,它将返回文档中所有元素的列表,元素排列的顺序就是它们在文档中的顺序。
注释:传递给 getElementsByTagName() 方法的字符串可以不区分大小写。
var x = document.getElementsByTagName("INPUT")[0];
alert(x.tagName) // "INPUT"
document.write()
write() 方法可向文档写入 HTML 表达式或 JavaScript 代码。
可列出多个参数(exp1,exp2,exp3,...) ,它们将按顺序被追加到文档中。
document.write("Hello World!");
关于Document的更多属性方法可查W3C:HTML DOM Document 对象
DOM Element
简介:
在 HTML DOM 中,Element 对象表示 HTML 元素(所有 HTML 元素是元素节点)。
Element 对象可以拥有类型为元素节点、文本节点、注释节点的子节点。
NodeList 对象表示节点列表,比如 HTML 元素的子节点集合。
元素也可以拥有属性。属性是属性节点(参见DOM Attribute)。
element.parentNode
parentNode 属性以 Node 对象的形式返回指定节点的父节点。
如果指定节点没有父节点,则返回 null。
H1
var h = document.getElementsByTagName("H1")[0];
alert(h.parentNode.nodeName); // "DIV"
element.style
HTMLElement.style 属性返回一个 CSSStyleDeclaration 对象,表示元素的 内联style 属性(attribute),但忽略任何样式表应用的属性。 通过 style 可以访问的 CSS 属性列表,可以查看 CSS Properties Reference。
H1
var h = document.getElementsByTagName("H1")[0];
h.setAttribute("style","font-size:100px;color: blue;")
elt.style.cssText = "color: blue"; 设置多个样式属性
elt.setAttribute("style", "color: blue"); 设置多个样式属性
elt.style.color = "blue"; 直接设置样式属性
var st = elt.style; st.color = "blue"; 间接设置样式属性
通常,要了解元素样式的信息,仅仅使用 style 属性是不够的,这是因为它只包含了在元素内嵌 style 属性(attribute)上声明的的 CSS 属性,而不包括来自其他地方声明的样式,如
部分的内嵌样式表,或外部样式表。要获取一个元素的所有 CSS 属性,你应该使用 window.getComputedStyle()。element.childNodes;
childNodes 属性返回节点的子节点集合,以 NodeList 对象。
提示:您可以使用 length 属性来确定子节点的数量,然后您就能够遍历所有的子节点并提取您需要的信息。
Node.childNodes 返回包含指定节点的子节点的集合,该集合为即时更新的集合(live collection)。
获得的Nodelist是实时更新的,如果你新增一个子节点,下次调用chilNodes属性返回的Nodelist会变化(更新)。
Nodelist不是数组!这一点很重要
this is H1
this is H2
Element P
var div = document.getElementsByTagName("div")[0];
var child_nodes = div.childNodes;
var h1 = document.getElementsByTagName("h1")[0];
var h2 = document.getElementsByTagName("h2")[0];
// 为了看Nodelist里有什么东西,for循环出来一堆看不懂的东西:)
for (var i=0;i
document.write(child_nodes[i]+"
")
}
document.write("
");
// Nodelist有length属性,这里值为5,并且它可以删除掉
console.log(child_nodes.length); // 5
delete child_nodes.length;
console.log(child_nodes.length); // "undefined"
/**Nodelist里元素(节点)对象排序按照HTML源码的顺序排下来,第一个文本节点从div标签后开始,到H1标签前,在Nodelist里表示就是[0]
* 第二个是H1元素节点,但是H1标签后有换行空余,这里构成了H1标签后面的文本节,即Nodelist[2]
* 同理,H2标签后因为换行符,到DIV结束标签前产生的空余内容构成了Nostlist[4]
*/
console.log(child_nodes[0].nodeType); // nodeType:3,表示文本
console.log(child_nodes[1]===h1) // true
child_nodes[1].style.background = "orange"; // 返回的Nodelist因为包括子节点,可以设置样式
// div的Nodelist里[2][11]的文本节点是什么? result:是因为H1,H2元素节点换行产生的空余,这里因为可以填充文本所以也算是文本节点
console.log(h1.childNodes.length); // 1
// H1元素的Nodelist里只有文本节点,哪怕没有像
// 再使用一个全新的div来试验,div2我们不让它产生空隙
var div2 = document.getElementById("div2").childNodes;
for (var j=0;j
document.write(j+1+"个"+div2[j]+"
")
}
/*我们可以看到,这样就只有两个Node,第一个是DIV文本,第二个是P元素节点,
* 从
* 第一个DIV,如果用IE解释,它的Nodelist只有三个节点,其他浏览器就有5个子节点*/
DOM Attribute
Attr 对象
在 HTML DOM 中,Attr 对象表示 HTML 属性。
HTML 属性始终属于 HTML 元素。
NamedNodeMap 对象
在 HTML DOM 中,NamedNodeMap 对象表示元素属性节点的无序集合。
NamedNodeMap 中的节点可通过名称或索引(数字)来访问。
var Input = document.getElementsByTagName("input")[0];
// console.log(Input.attributes) // "[object NamedNodeMap]"
for (var b in Input) { // 查看input元素节点里的属性方法
document.write(b+"
")
}
document.write("
")
for (var j in Input.attributes) { // input.attributes,即NameNodeMap对象
document.write(j+"
")
}
document.write("
")
for (var x in Input.attributes[0]) { // input元素节点里的属性节点,每个HTML标准属性都是一个属性节点
document.write(x+"
")
}
for-in出来的东西太多就不贴图了
DOM元素含有的这两个东西,虽然完全不是一回事,但却又紧密联系在一体,不细细体会,还真不好分清。Property-属性,Attribute-特性,每一个dom元素都有一个attributes属性来存放所有的attribute节点,通过getAttribute()和setAttribute()方法来进行获取和操作。
Property就是一个属性,如果把DOM元素看成是一个普通的object对象,那么property就是以name=value形式存放在Object中的属性操作很简单
element.gameid = 880; // 添加
console.log( elem.gameid ) // 获取
这两个东西有什么联系和区别呢?
首先,很多attribute节点有一个相应的property属性,如例子中的input元素的id和type既是attribute也有property,不管哪种方式都可以访问和修改,但是对于自定义的attribute节点,或者自定义property,两者就没有关系了,对于IE6-7来说,没有区分attribute和property。具体的讲解可以考attribute和property的区别,很详细。
这段话也是我在百度知道上找的,目前我的理解也很不全面,先摆着以后慢慢看。先知道怎么使用这些属性节点和NameNodeMap对象。后续要弄懂分清除Property和Attrubute两个对象
引用几个颇有见地的文章吧:
attribute
input节点有很多属性(attribute):‘type’,'id','value','class'以及自定义属性,在DOM中有setAttribute()和getAttribute()读写DOM树节点的属性(attribute)
PS:在这里的getAttribute方法有一个潜规则,部分属性(input的value和checked)通过getAttribut取到的是初始值
Property
javascript获取到的DOM节点对象,比如a 你可以将他看作为一个基本的js对象,这个对象包括很多属性(property),比如“value”,“className”以及一些方法,setAttribute,getAttribute,onclick等,
所有在日常的工作中,推荐是使用 property,这样事情处理起来比较简单一些,attribute永远是字符串。
来看几个常用属性/方法
获取、设置、删除属性节点常用方法:
elementNode.attributes(属性返回包含被选节点属性的 NamedNodeMap)
elementNode.getAttribute(name)(方法通过名称获取属性的值)
elementNode.setAttribute(name, value)(方法创建或改变某个新属性)
elementNode.removeAttribute(name)(方法通过名称删除属性的值)
attributes.value
设置或返回属性的值
var i = document.getElementById("input");
console.log(i.attributes.value.value)
这段代码首先获得inputHTML元素,然后调用attributes返回NameNodeMap属性节点集合,里面的属性以键值对方式存在,之后调用value属性的属性值。
attribute.setNamedItem()
setNamedItem() 方法向 nodeMap 添加指定的节点。
如果此节点已存在,则将替换该节点,并返回被替换的节点,否则返回值是 null。
var i = document.getElementById("input");
var c = document.createAttribute("class");
c.nodeValue = "cla";
i.attributes.setNamedItem(c)
创建属性节点,设置节点值,添加到元素节点下,然后设置属性节点,这里用的是attributes方法,即namednodemap.removeNamedItem(nodename)
添加属性节点也可以使用element.setAttributeNode(attributenode)方法;
关于更多:HTML DOM Attribute 对象,其中提到了不要在属性节点上使用节点对象的属性和方法
关于事件一章我会另开一篇博文继续研究