十一、DOM或以树型展示的Web页面
定义DOM的基础设施,包括模式(schema)和应用编程接口(API)。DOM的核心是语言无关的API,可以用任何语言实现,DOM的核心就是提供修改、删除或创建Web页面内容所需的各种功能。主要的两个API即HTML和Core。它们都能实现相同的功能,但HTML具有很好的自描述性,有专门的对象名称,如果想创建自己的可复用对象库,最好使用更通用的Core。
(一)HTML API
DOM HTML API是一组对象接口(接口是一个表示特定页面元素的对象,它没有构造函数,对象是通过其他函数创建的)集,而不是实际的对象类。通过这些接口可以访问原有的或新创建的页面对象。HTML API从HTMLElement中继承了属性和方法,还从核心的Node对象中继承。而HTML对象是从HTMLElement中继承的,拥有以下属性
id | 元素标识符 |
title | 元素内容的描述性标题 |
lang | 元素及其内容的语言 |
dir | 文字方向(从左到右) |
className | 等价于class属性 |
var img = document.images[0];
img.src="1.png";
img.width="800";
这种通过JS修改元素的技术,也是解决XHTML严格要求的一种方法,在开发更为复杂的Ajax应用时,该技巧是向页面元素添加自定义属性的好方法。
HTML接口对象提供了创建、删除或以其他方式修改相关联的页面元素的方法。特别是table元素,提供了一组特定的方法和特定的对象,但要创建这些接口对象,需要使用一个工厂方法。
var tb1 = document.getElementById('table1');
tb1.border = "5px";
tb1.cellPadding = "5px";
var img = document.getElementById('image1');
img.vspace = "10"
var row1 = tb1.insertRow(-1);
var cell1 = row1.insertCell(0);
var cell2 = row1.insertCell(1);
var txt1 = document.createTextNode("somename");
var txt2 = document.createTextNode("somename");
cell1.appendChild(txt1);
cell2.appendChild(txt2);
- insertRow方法创建HTMLTableRowElement对象,用来插入表格行;
- insertCell方法(HTMLTableRowElement对象接口中)创建HTMLTableCellElement对象,用来插入单元格;
- createTextNode方法(document对象中)创建一个text对象,传入字符串;
- appendChild方法将text对象添加到表格单元格中;
- removeCell和removeRow方法来删除表格单元格和表格行;
HTML接口并不直接表示特定和HTML元素,而是表示对象的集合(HTML集合)。
HTMLCollection接口只有一个名为length的属性,还有两个能够返回集合中特定对象的方法:item(数字参数)和namedItem(字符串参数)。
(二)Core API
产业界开始不再使用HTML,而逐渐倾向于使用XML和XHTML。对于它们而言,HTML API依然有效,但名为Core API的另一组接口就流行起来。Core提供了一个规范,可以通过两种不同的技术访问内容树的节点:查询特定类型的所有标签;遍历不同的层级。不仅可以从树上读取节点,还可以删除或创建新的节点。
1.Node对象(提供层次结构的文档树支持)
文档的元素描述为一个节点(node)集合,它们之间是以层次结构的树形结构相连接的。在DOM树结构中,属于另一个元素的一个元素称为子节点,作为子节点的容器元素称为父节点,父节点相同的一级元素称为兄弟节点。每一个节点都拥有Core的Node对象中定义的所有基本属性集和基本方法集:
nodeName | 对象名称(head元素即HEAD) |
nodeValue | 如果不是一个元素,返回对象值 |
nodeType | 用数字表示的节点类型 |
parentNode | 当前节点的父节点 |
childNodes | 由其子节点组成的NodeList,前提是存在子节点 |
firstChild | 由子节点组成的NodeList中的第一个节点 |
lastChild | 由子节点组成的NodeList中的最后一个节点 |
previousSibling | 表示该列表中的前一个节点 |
nextSibing | 表示该列表中的下一个节点 |
attributes | 一个NamedNodeMap,是该元素的属性列表 |
ownerDocument | 拥有的document对象 |
namespaceURI | 针对节点的命名空间的URI |
Prefix | 针对节点的命名空间的前缀 |
localName | 指定namespace的URI的话,它表示节点的本地名 |
insertBefore(newChild,refChild) | 在refChild指定的现有节点前插入新节点 |
replaceChild(newChild,oldChild) | 替换现有节点 |
removeChild(oldChild) | 删除现有子节点 |
appendChild(newChild) | 为文档添加子节点。 |
//输出节点属性
function outputNode (nd) {
var strnode = "Node type:" + nd.nodeType;
strnode += "Node Name:" + nd.nodeName;
strnode += "Node Value:" + nd.nodeValue;
if (nd.style) {
var clr = "Black";
nd.style.backgroundColor = clr;
strNode +="backgroundColor: "+clr;
}
alert(strnode);
}
节点中的nodeType属性是数字型的,也可利用常量访问每种类型的节点
ELEMENT_NODE | 1 |
ATTRIBUTE_NODE | 2 |
TEXT_NODE | 3 |
CDATA_SECTION_NODE | 4 |
ENTITY_REFERENCE_NODE | 5 |
ENTITY_NODE | 6 |
PROCESSING_INSTRUCTION_NODE | 7 |
COMMENT_NODE | 8 |
DOCUMENT_NODE | 9 |
DOCUMENT_TYPE_NODE | 10 |
DOCUMENT_FRAGMENT_NODE | 11 |
NOTATION_NODE | 12 |
注:该常量的实现并不普遍,IE没有实现这些常量
2.document对象(所有页面元素的所有者/父节点)
Web页面文档之间的核心接口。它提供的方法能够创建和删除页面元素,也能控制它们在页面中的位置。它还提供了两个访问页面元素的方法:getElementById和getElementByTagName。
getElementByTagName方法将返回一个节点列表(NodeList),它表示的是页面中指定标签的所有页面元素
function highlight () {
var eletag = prompt("Enter tag element name:","p");
var nodes = document.getElementsByTagName(eletag);
for (var i = 0; i < nodes.length; i++) {
var mynode = nodes[i];
mynode.style.backgroundColor = highlightcolor;
}
}
工厂方法 | 创建的对象 | 描述 |
---|---|---|
createElement(tagname) | element | 创建特定类型的元素 |
createDocumentFragment | DocumentFragment | 轻量级的document对象,用于获取文档树中的一个部分 |
createTextNode(data) | Text | 保存页面中的文本 |
createComment(data) | Comment | XML注释 |
createCDATASection(data) | CDATASection | CDATA区段(section) |
CreateProcessingInstructions (target,data) |
ProcessingInstruction | XML处理指令 |
createAttribute(name) | Attr | 元素属性 |
CreateElementNS (namespaceURI,qualitifiedName) |
Element | 创建带有命名空间的元素 |
CreateAttributeNS (namespaceURI,qualitifiedName) |
Attr | 创建带有命名空间的属性 |
CreateEntityReference(name) | EntityReference | 创建后面放置的元素 |
var div = document.createElement("div");
var p = document.createElement("p");
var text = document.createTextNode("text");
p.appendChild(text);
div.appendChild(p);
如果要在DOM树中添加大量的节点,可以先使用createDocumentFragment方法创建一个DocumentFragment,接着为其添加节点,然后将DocumentFragment添加到文档树中,这样性能会加强。
3.Element对象(访问其上下文内元素)
文档中的所有页面元素都将从Element元素中继承一个API或多个属性。其主要功能是获取和设置属性值以及检查属性是否存在:
element.getAttribute(name);
element.setAttribute(name,value);
element.removeAttribute(name);
element.getAttributeNode(name);
element.setAttributeNode(attr);
element.removeAttributeNode(attr);
element.hasAttribute(name);
var div = document.getElementById("divname");
var p = div.getElementsByTagName("p");