说说 JavaScript 在 DOM 2、3 级的变化(相对于 DOM 1 级)

来源:互联网 发布:photoshop7 mac破解版 编辑:程序博客网 时间:2024/06/05 17:53

DOM 2、3 级扩展了 DOM API,以便满足操作 XML 的需求,同时提供更好的错误处理以及特性检测能力。

下列代码可以确定浏览器是否支持这些 DOM 功能:

var supportsDOM2Core = document.implementation.hasFeature("Core", "2.0");var supportsDOM3Core = document.implementation.hasFeature("Core", "3.0");var supportsDOM2HTML = document.implementation.hasFeature("HTML", "2.0");var supportsDOM2Views = document.implementation.hasFeature("Views", "2.0");var supportsDOM2XML = document.implementation.hasFeature("XML", "2.0");

注意: 本文只讨论那些已有浏览器实现的部分!


1 针对 XML 命名空间的变化

XHTML 支持 XML 的命名空间,所以我们接下来要说的都是 XHTML 文档。

命名空间使用 xmlns 特性来指定:

<html xmlns="http://www.w3.org/1999/xhtml">    <head>        <title>Example XHTML page</title>    </head>    <body>        Hello world!    </body></html>

这里所有的元素默认都是 XHTML 命名空间中的元素。可以为 XML 命名空间创建前缀:

<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml">    <xhtml:head>        <xhtml:title>Example XHTML page</xhtml:title>    </xhtml:head>    <xhtml:body>        Hello world!    </xhtml:body></xhtml:html>

在混合使用多种语言的情况下,可以使用命名空间避免语言之间的冲突:

<html xmlns="http://www.w3.org/1999/xhtml">    <head>        <title>Example XHTML page</title>    </head>    <body>        <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 100 100" style="width:100%; height:100%">            <rect x="0" y="0" width="100" height="100" style="fill:red"/>        </svg>    </body></html>

在这个例子中, <svg> 元素所包含的所有子元素,以及它们的特性,都被认为是 属于 http://www.w3.org/2000/svg 的命名空间。

DOM 2 级核心为大多数的 DOM 1 级方法,提供了特定于命名空间的版本。

1.1 Node 类型的变化

DOM 2 级新增了这些属性:

属性名 说明 localName 不带命名空间前缀的节点名称。 namespaceURI 命名空间 URI 或 null。 prefix 命名空间前缀或 null。

当节点使用了命名空间前缀时,其 nodeName 等于 prefix+":"+localName

<s:svg id="svg" xmlns:s="http://www.w3.org/2000/svg" version="1.1"       viewBox="0 0 100 100" style="width:100%; height:100%">    <s:rect x="0" y="0" width="100" height="100" style="fill:red"/></s:svg>

对于 <s:svg> 元素而言,它的 localName 是 svg,tagName 是 s:svg

DOM 2 级新增了这些属性:

属性名 说明 isDefaultNamespace(namespaceURI) 指定的 namespaceURI 是当前节点默认的命名空间,返回 true。 lookupNamespaceURI(prefix) 返回给定 prefix 的命名空间。 lookupPrefix(namespaceURI) 返回给定 namespaceURI 的前缀。

针对刚才的例子,可以执行下列代码:

console.log(document.body.isDefaultNamespace("http://www.w3.org/1999/xhtml"));//truevar svg = document.getElementById("svg");console.log(svg.lookupPrefix("http://www.w3.org/2000/svg"));//sconsole.log(svg.lookupNamespaceURI("s"));//http://www.w3.org/2000/svg

在取得了一个节点,但不知道该节点与文档中的其他元素的关系时,这些方法就很有用!

1.2 Document 类型的变化

DOM 2 级新增了这些方法:

方法名 说明 createElementNS(namespaceURI, tagName) 使用给定的 tagName 创建一个属于命名空间 namespaceURI 的新元素。 createAttributeNS(namespaceURI,attributeName) 使用给定的 attributeName 创建一个属于命名空间 namespaceURI 的新属性。 getElementsByTagNameNS(namespaceURI, tagName) 返回属于命名空间 namespaceURI 的 tagName 元素的 NodeList。
//创建一个新的 SVG 元素var svg = document.createElementNS("http://www.w3.org/2000/svg,"svg");//创建一个属于某个命名空间的新特性var att = document.createAttributeNS("http:/xxx,"random");//取得所有 XHTML 元素var elems = document.getElementsByTagNameNS("http://www.w3.org/1999/xhtml","*");

只有文档中存在多个命名空间时,这些方法才有用!

1.3 Element 类型的变化

DOM 2 级新增了这些方法:

方法名 说明 getAttributeNS(namespaceURI,localName) 取得属于命名空间 namespaceURI 且名为 localName 的特性。 getAttributeNodeNS(namespaceURI,localName) 取得属于命名空间 namespaceURI 且名为 localName 的特性的节点。 getElementsByTagNameNS(namespaceURI,tagName) 返回属于命名空间 namespaceURI 的 tagName 元素的 NodeList。 hasAttributeNS(namespaceURI,localName) 确定当前元素是否有在命名空间 namespaceURI 中,且名为 localName 的特性。 hasAttribute(localName) 确定当前元素是否有名为 localName 的特性。 removeAttributeNS(namespaceURI,localName) 删除属于命名空间 namespaceURI 且名为 localName 的特性。 setAttributeNS(namespaceURI,qualifiedName,value) 设置属于于命名空间 namespaceURI 且名为 qualifiedName 的特性的值为 value。 setAttributeNodeNS(attNode) 设置属于命名空间 namespaceURI 的特性节点。

1.4 NamedNodeMap 类型的变化

主要是新增了与命名空间有关的方法,因为我们一般都是通过元素来访问特性,所以这些方法很少使用,所以这里就不一一列举啦 O(∩_∩)O~

2 其他方面的变化

其他的变化是为了确保 API 更可靠、更完整。

2.1 DocumentType 类型的变化

DocumentType 类型新增了 publicId、systemId 以及 internalSubset 属性。

<!DOCTYPE HTML PUBLIC "-//W3C/DTD HTML 4.01//EN","http://www.w3.org/TR/html4/strict.dtd">

这段代码中,publicId 是 -//W3C/DTD HTML 4.01//EN,systemId 是 http://www.w3.org/TR/html4/strict.dtd。在支持 DOM 2 级的浏览器中,可以这样运行:

document.doctype.publicId;document.doctype.systemId;

在实践中,很少用到这两个属性。

internalSubset 表示的是包含在文档类型声明中的额外定义:

<!DOCTYPE HTML PUBLIC "-//W3C/DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"[<!ELEMENT name (#PCDATA)>] >

document.doctype.internalSubset 可以得到 <!ELEMENT name (#PCDATA)>,它在 HTML 中很少用到,可能在 XML 中会用到吧 O(∩_∩)O~

2.2 Document 类型的变化

2.2.1 importNode()

从一个文档取得的节点,导入到另一个文档。注意,每一个节点都有一个 ownerDocument 属性,表示所属的文档。

它接受两个参数:要复制的节点以及是否复制子节点的布尔值,返回的结果是原来节点的副本,它的所有权归当前文档所有:

var newNode = document.importNode(oldNode, true);//导入节点以及所有的子节点document.body.appendChild(newNode);

这个方法在 XML 中用的比较多。

2.2.2 defaultView 属性(DOM 2 级视图)

它保存着指向拥有给定文档的窗口或者框架的指针。除 IE 外其他浏览器都支持这个属性。IE 使用的是一个等价属性 parentWindow,所有要确定当前文档的归属窗口,可以这样使用:

var parentWindow = document.defaultView || document.parentWindow;

2.2.3 createDocumentType()(DOM 2 级核心中,document.implentation 的新方法)

它接受 3 个参数:文档类型名称、publicId、SystemId:

var doctype = document.implentation.createDocumentType("html","-//W3C/DTD HTML 4.01//EN","http://www.w3.org/TR/html4/strict.dtd");

它只在创建新文档时才有用。

2.2.4 createDocument()(DOM 2 级核心中,document.implentation 的新方法)

它接受 3 个参数:文档中元素的 namespaceURI、文档元素的标签名、新文档的文档类型,下面的代码会创建一个新的 XML 文档:

var doctype = document.implentation.createDocumentType("html","-//W3C/DTD HTML 4.01//EN","http://www.w3.org/TR/html4/strict.dtd");var doc = document.implentation.createDocument("http://www.w3.org/1999/xhtml","html",doctype);

注意,这个新文档只有 <html> 元素!

2.2.5 createHTMLDocument()(DOM 2 级核心中,document.implentation 的新方法)

它用于创建一个完整的 HTML 文档(包含<html>、<head>、<title>、<body>元素)。它接受一个参数,即要创建文档的标题(<title>):

var htmldoc = document.implementation.createHTMLDocument("New Doc");console.log(htmldoc.title);//New Docconsole.log(typeof htmldoc.body);//object

2.3 Node 类型的变化

2.3.1 isSupported()

用于确定当前节点具有什么能力。它接受两个参数:特性名和特性版本号:

if (document.body.isSupported("HTML","2.0")){    ...}

这个方法跟具体浏览器的实现关系非常大,有可能与实际的能力不一致,所以最好还是使用能力检测会更稳妥些。

2.3.2 isSameNode() 与 isEqualNode() (DOM 3 级)

它们都接受一个节点参数,如果传入的节点与引用的节点相同或者相等时,返回 true。相同,指的是两个节点引用的是同一个对象。相等,指的是两个节点是相同的节点,它们具有相等的属性值:

var div1 = document.createElement("div");div1.setAttribute("class", "box");var div2 = document.createElement("div");div2.setAttribute("class", "box");console.log(div1.isSameNode(div1));//trueconsole.log(div1.isEqualNode(div1));//trueconsole.log(div1.isSameNode(div2));//false

2.4 框架的变化

在 DOM 2 级中,框架(HTMLFrameElement) 和内嵌框架(HTMLFrameElement)都新增了 contentDocument 属性,它指向框架内容的文档对象。IE 8 之前不支持这个属性,但可以使用等价的 contentWindow 属性,因此可以这样编写跨浏览器的访问内嵌框架的文档对象:

var iframe = document.getElementById("myIframe");var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

注意: 访问框架或内嵌的文档对象会受到跨域安全策略的限制。如果某个框架中的页面来自其他域或不同子域,或者使用了不同的协议,那么访问时,就会发生错误。


原创粉丝点击