本文正在翻译中,原文请参考 Migrate apps from Internet Explorer to Mozillajavascript
当Netscape最初推出Mozilla浏览器的时候, 特别考虑对W3C标准的支持. 因此Mozilla并不对Netscape Navigator 4.x 和微软IE遗留的源码作向后支持. 例如, Mozilla不支持<layer>
, 我在后面会进行讨论. 那些像IE4同样, 在W3C标准概念以前开发的浏览器遗留了不少毛病. 在这篇文章里, 我将描述Mozilla的"Quirks Mode". 这个模式对IE和其余遗留下来的浏览器提供强大的向后HTML源码兼容性.css
我还会归纳一些非标准的技术. 好比XMLHttpRequest和富文本编辑那些Mozilla支持, 但到目前为止尚未W3C标准的(技术). 它们包括:html
尽管网络标准明确存在, 不一样浏览器表现仍是不一样 (其实, 同一浏览器在不一样操做系统上也可能不同). 不少浏览器, 包括IE, 也支持W3C以前的API, 并从没普遍地为W3C兼容的API进行支持.java
在我详细论述Mozilla和IE的不一样以前, 我要先讲一下一些关于如何令网络应用程序能够扩展来对从此新的浏览器支持的基本方法.node
由于不一样浏览器有时针对相同的功能, 使用不一样的API, 你常常能够在源码中找到多个用来区分浏览器的if() else()
的语句块. 下面这段源码是针对IE的 (只有用IE才被解析) :web
. . . var elm; if (ns4) elm = document.layers["myID"]; else if (ie4) elm = document.all["myID"]
上面的源码是不可扩展的, 因此若是你想让它支持某个新的浏览器, 你必须把全部相似这样的源码块更新.编程
想消除每有新浏览器就要从新编写的问题, 最简单的方法就是抽取这个功能. 相比于多个if() else()
, 你应该将经常使用任务抽取成独立的函数, 来提升效率. 这不只让你的源码简单易读, 更简化了对新浏览器增长支持(的步骤):数组
var elm = getElmById("myID"); function getElmById(aID){ var element = null; if (isMozilla || isIE5) element = document.getElementById(aID); else if (isNetscape4) element = document.layers[aID]; else if (isIE4) element = document.all[aID]; return element; }
以上的代码仍然有“浏览器监听”的问题,即探测用户正在使用哪个浏览器。浏览器监听一般经过用户代理完成,例如:浏览器
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031016
使用用户代理监听浏览器提供了使用中的浏览器的详细信息,然而当浏览器的新版原本临时,处理用户代理的代码常常出错,这样就须要修改代码。服务器
若是浏览器的种类可有可无(假设你已经阻止了不被支持的浏览器访问网络应用),使用浏览器的能力或对象的特点支持来进行监听更好也更可靠。你一般能够JavaScript中测试必需的功能来作到这一点。例如,比起如下的代码:
if (isMozilla || isIE5)
你将更愿意使用:
if (document.getElementById)
这将容许支持W3C标准规范的浏览器(例如Opera或Safari)无须改动地工做。
然而,用户代理监听只有在精确度显得重要时才有意义,例如在你审核一个浏览器是否符合网络应用程序的版本要求或试图解决bug的状况下。
JavaScript也容许顺序条件语言(inline conditional statements)以助于代码的可读性:
var foo = (condition) ? conditionIsTrue : conditionIsFalse;
例如,你可使用如下代码来取回一个元素(element):
function getElement(aID){ return (document.getElementById) ? document.getElementById(aID) : document.all[aID]; }
首先,我要讨论HTML在Mozilla和Internet Explorer中表现的区别。
传统浏览器将工具提示引进HTML中,在连接上显示它们,并使用alt
属性的值做为工具提示的内容。最新的W3C HTML规范创造了title
属性,意欲包含连接的详细描述。现代浏览器将使用title
属性来显示工具提示,且Mozilla只支持为此属性显示工具提示而不支持alt
属性。
HTML markup can contain several entities, which the W3C web standards body has defined. You can reference entities through their numerical or character reference. For example, you can reference the white space character #160 with  
or with its equivalent character reference
.
HTML 置标包含了W3C 网页标准体定义的几个标准。你能够经过引用数字或字符来引用实体。例如,你可使用 
以引用白色空格字符#160;或使用它的等价字符引用
。
Some older browsers, such as Internet Explorer, had such quirks as allowing you to use entities by replacing the ;
(semi-colon) character at the end with regular text content:
某些旧式浏览器如Internet Explorer,有这样的惯例,即容许在常规文本内容末尾替换;
(分号)字符以使用实体:
  Foo    Foo
Mozilla will render the above  
as white spaces, even though that is against the W3C specification. The browser will not parse a  
if it is directly followed by more characters, for example:
Mozilla提供上述 
做为白色空格,即使这违反了W3C规范。若是 
后直接连着更多的字符,浏览器不会解析此代码,例如:
 12345
This code does not work in Mozilla, since it goes against the W3C web standards. Always use the correct form (
) to avoid browser discrepancies.
这段代码在Mozilla中无效,由于它违反了W3C标准。请始终使用正确的格式(
) 以免浏览器不兼容。
The Document Object Model (DOM) is the tree structure that contains the document elements. You can manipulate it through JavaScript APIs, which the W3C has standardized. However, prior to W3C standardization, Netscape 4 and Internet Explorer 4 implemented the APIs similarly. Mozilla only implements legacy APIs if they are unachievable with W3C web standards.
文档对象模型(DOM)一般就是包含全部文档元素的树型结构体。开发者能够用一些javascript API来控制这个结构体,固然这些API是基于W3C标准的。在W3C标准公布前Netscape 4和IE 4 就实现了类似的功能,而Mozilla仅实现了一些成为最终W3C标准的API。
文档对象模型(DOM)一般就是包含全部文档元素的树型结构体。开发者能够用一些javascript API来操做这个结构体,固然这些API是W3C标准化过的。在W3C标准公布前,Netscape 4和IE 4 就已经编写了类似的API;Mozilla根据W3C标准重写了API,只有那些在W3C中没有定义的API,Mozilla才将其保留了下来。
To retrieve an element reference using the cross-browser approach, you use document.getElementById(aID)
, which works in Internet Explorer 5.0+, Mozilla-based browsers, other W3C-compliant browsers and is part of the DOM Level 1 specification.
为经过跨浏览器途径检索单元引用,你可使用document.getElementById(aID)
,它是DOM Level 1 规范的一部分,并在Internet Explorer 5.0+,基于Mozilla的浏览器,以及其它适用W3C标准的浏览器中起做用。
Mozilla does not support accessing an element through document.elementName
or even through the element's name, which Internet Explorer does (also called global namespace polluting). Mozilla also does not support the Netscape 4 document.layers
method and Internet Explorer's document.all
. While document.getElementById
lets you retrieve one element, you can also use document.layers
and document.all
to obtain a list of all document elements with a certain tag name, such as all <div>
elements.
Mozilla不支持经过document.elementName
抑或经过单元名称存取单元,而Internet Explorer 支持(这是一个糟糕的基于全局变量的实现)。Mozilla也不支持Netscape 4 document.layers
方法和Internet Explorer的document.all
.。在经过document.getElementById
索引单元的同时,你也可使用document.layers
和document.all
以获取带有特定标签名的全部文件单元列表,例如全部<div>
单元。
The W3C DOM Level 1 method gets references to all elements with the same tag name through getElementsByTagName()
. The method returns an array in JavaScript, and can be called on the document
element or other nodes to search only their subtree. To get an array of all elements in the DOM tree, you can use getElementsByTagName("*")
.
基于W3C DOM1的getElementsByTagName()返回一个具备相同标签元素的索引,在JavaScript中,它返回一个包含全部元素的数组对像,并可被 document
单元或其它节点访问以查找它们本身的子树。你可使用getElementsByTagName("*")
以获取DOM树中全部单元的阵列。
The DOM Level 1 methods, as shown in Table 1, are commonly used to move an element to a certain position and toggle its visibility (menus, animations). Netscape 4 used the <layer>
tag, which Mozilla does not support, as an HTML element that can be positioned anywhere. In Mozilla, you can position any element using the <div>
tag, which Internet Explorer uses as well and which you'll find in the HTML specification.
DOM Level 1 程序(见表1)一般被用来移动单元到一个特定的位置并切换它的可视度(菜单,动画等)。Netscape 4 用Mozilla不支持的<layer>
标签做为可被任意放置的HTML单元。在Mozilla中,你可使用<div>
标签来放置任何单元,正如你在HTML规范中所见,它也一样被Internet Explorer 使用。
程序 | 描述 |
---|---|
document.getElementById( aId ) | 对指定ID的单元返回索引。 |
document.getElementsByTagName( aTagName ) | 对指定文档中名称的单元返回数组。 |
Mozilla supports the W3C DOM APIs for traversing the DOM tree through JavaScript (see Table 2). The APIs exist for each node in the document and allow walking the tree in any direction. Internet Explorer supports these APIs as well, but it also supports its legacy APIs for walking a DOM tree, such as the children
property.
为经过Javascript跨越DOM树型,Mozilla支持W3C DOM的应用编程接口(API) (见表2)。这种API存在于每个文档节点中,并容许在树形中沿任意方向行走。Internet Explorer一样支持这些API,不过它也支持本身继承的API以进行树形行走,例如children
属性。
属性/程序 | 描述 | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
childNodes | Returns an array of all child nodes of the element.返回单元中全部子节点的数组。 | ||||||||||||||||||||||||||
firstChild | Returns the first child node of the element.返回单元中第一个子节点。 | ||||||||||||||||||||||||||
getAttribute( aAttributeName ) | Returns the value for the specified attribute.返回指定属性的值。 | ||||||||||||||||||||||||||
hasAttribute( aAttributeName ) | Returns a boolean stating if the current node has an attribute defined with the specified name.若当前节点有定义为指定名称的属性则返回布尔状态。 | ||||||||||||||||||||||||||
hasChildNodes() | Returns a boolean stating whether the current node has any child nodes.不管当前节点有无子节点,返回布尔状态。 | ||||||||||||||||||||||||||
lastChild | Returns the last child node of the element.返回单元中最后一个子节点。 | ||||||||||||||||||||||||||
nextSibling | Returns the node immediately following the current one.返回紧接当前的节点。 | ||||||||||||||||||||||||||
nodeName | Returns the name of the current node as a string.以字符串形式返回当前节点的名称。 | ||||||||||||||||||||||||||
nodeType | Returns the type of the current node.返回当前节点的类型。
|
||||||||||||||||||||||||||
nodeValue | Returns the value of the current node. For nodes that contain text, such as text and comment nodes, it will return their string value. For attribute nodes, the attribute value is returned. For all other nodes, null is returned. 返回当前节点的值。对包含文本的节点,例如文本节点和注释节点,将返回它们的字符串值。对属性节点则返回属性值。对其它全部节点返回 |
||||||||||||||||||||||||||
ownerDocument | Returns the document object containing the current node.返回包含当前节点的document 对象。 |
||||||||||||||||||||||||||
parentNode | Returns the parent node of the current node.返回当前节点的母节点。 | ||||||||||||||||||||||||||
previousSibling | Returns the node immediately preceding the current one.返回当前节点的前一个节点。 | ||||||||||||||||||||||||||
removeAttribute( aName ) | Removes the specified attribute from the current node.移除当前节点中的指定属性。 | ||||||||||||||||||||||||||
setAttribute( aName, aValue ) | Sets the value of the specified attribute with the specified value.将指定属性设置为指定值。 |
Internet Explorer has a nonstandard quirk, where many of these APIs will skip white space text nodes that are generated, for example, by new line characters. Mozilla will not skip these, so sometimes you need to distinguish these nodes. Every node has a nodeType
property specifying the node type. For example, an element node has type 1, while a text node has type 3 and a comment node is type 8. The best way to only process element nodes is to iterate over all child nodes and only process those with a nodeType of 1:
Internet Explorer有个非标准的例外,即许多这些API会跳过生成的白色空格文本节点(到新一行的字符,比方说)。Mozilla则不会跳过,因此有时你须要分清这些节点。每一个节点都有一个nodeType
属性,标明了节点的类型,例如,单元节点是1型,而一个文本节点是3型,注释节点是8型。只处理单元节点的最好方法就是循环全部子节点而惟独处理其中1型的:
HTML: <div id="foo"> <span>Test</span> </div> JavaScript: var myDiv = document.getElementById("foo"); var myChildren = myXMLDoc.childNodes; for (var i = 0; i < myChildren.length; i++) { if (myChildren[i].nodeType == 1){ // element node }; };
Mozilla supports the legacy methods for adding content into the DOM dynamically, such as document.write
, document.open
and document.close
. Mozilla also supports Internet Explorer's innerHTML
method, which it can call on almost any node. It does not, however, support outerHTML
(which adds markup around an element, and has no standard equivalent) and innerText
(which sets the text value of the node, and which you can achieve in Mozilla by using textContent
).
Mozilla支持动态添加内容进DOM的旧式程序,例如document.write
,document.open
与document.close
。Mozilla也支持Internet Explorer的innerHTML
程序,它能够访问几乎全部节点。然而它并不支持outerHTML
(添加一个单元的置标,且没有标准的等价程序)和innerText
(设置节点的文本值,这能够用Mozilla中的textContent
)来完成)。
Internet Explorer has several content manipulation methods that are nonstandard and unsupported in Mozilla, including retrieving the value, inserting text and inserting elements adjacent to a node, such as getAdjacentElement
and insertAdjacentHTML
. Table 3 shows how the W3C standard and Mozilla manipulate content, all of which are methods of any DOM node.
Internet Explorer有几个在Mozilla中不标准、不被支持的内容操控程序,包括取回数值,在节点附近添加文本和单元,例如getAdjacentElement
与insertAdjacentHTML
。表3显示了W3C标准和Mozilla是如何操控内容的,它们都是任意DOM节点的程序。
程序 | 描述 |
---|---|
appendChild( aNode ) | Creates a new child node. Returns a reference to the new child node.建立一个新节点。返回此新节点的索引。 |
cloneNode( aDeep ) | Makes a copy of the node it is called on and returns the copy. If aDeep is true, it copies over the node's entire subtree.对被访问的节点制做备份并返回此备份。若是aDeep为真,则复制节点的整个子树。 |
createElement( aTagName ) | Creates and returns a new and parentless DOM node of the type specified by aTagName.以aTagName指定的数值建立并返回一个新的、无母节点的DOM节点。 |
createTextNode( aTextValue ) | Creates and returns a new and parentless DOM textnode with the data value specified by aTextValue.以aTextValue指定的数据值建立并返回一个新的、无母节点的DOM文本节点。 |
insertBefore( aNewNode, aChildNode ) | Inserts aNewNode before aChildNode , which must be a child of the current node.将aNewNode插入到aChildNode前(aChildNode(必须是当前节点的子节点)。 |
removeChild( aChildNode ) | Removes aChildNode and returns a reference to it.移除aChildNode并返回它的索引。 |
replaceChild( aNewNode, aChildNode ) | Replaces aChildNode with aNewNode and returns a reference to the removed node.以aNewNode替换aChildNode并返回被移除节点的索引。 |
For performance reasons, you can create documents in memory, rather than working on the existing document's DOM. DOM Level 1 Core introduced document fragments, which are lightweight documents that contain a subset of a normal document's interfaces. For example, getElementById
does not exist, but appendChild
does. You can also easily add document fragments to existing documents.
Mozilla creates document fragments through document.createDocumentFragment()
, which returns an empty document fragment.
Internet Explorer's implementation of document fragments, however, does not comply with the W3C web standards and simply returns a regular document.
出于性能的考虑,用户能够在内存中建立documents,而不使用已存在的文档的DOM。DOM第一级(Level 1)的核心引入了document fragments,一个包含部分document接口的轻量级documents。好比,有appendChild()而没有 getElementById()。读者也能够很方便的把document fragments添加到已存在的documents中。
Mozilla建立document fragments时调用document.createDocumentFragment(),它返回空的document fragment。
IE中document fragments的实现没有遵守W3C的标准,只是简单地返回普通的document。
译者注:document fragments和document是变量类型,故不翻译。
Most differences between Mozilla and Internet Explorer are usually blamed on JavaScript. However, the issues usually lie in the APIs that a browser exposes to JavaScript, such as the DOM hooks. The two browsers possess few core JavaScript differences; issues encountered are often timing related.
Mozilla与IE的差异之中,经常被责备的是JavaScript。然而,问题在于浏览器提供给JavaScript的API,好比DOM hook。两个浏览器的核心JavaScript存在一些差别;经常涉及有关时间消耗的问题。
The only Date
difference is the getYear
method. Per the ECMAScript specification (which is the specification JavaScript follows), the method is not Y2k-compliant, and running new Date().getYear()
in 2004 will return "104". Per the ECMAScript specification, getYear
returns the year minus 1900, originally meant to return "98" for 1998. getYear
was deprecated in ECMAScript Version 3 and replaced with getFullYear()
. Internet Explorer changed getYear()
to work like getFullYear()
and make it Y2k-compliant, while Mozilla kept the standard behavior.
关于Date
的惟一差别是getYear
函数。根据ECMAScript的定义(JavaScript听从这个定义),这个函数不是Y2k兼容的,在 2004年运行new Date().getYear()
会返回“104”。根据ECMAScript的定义,getYear
的返回值等于年份减去1900,例如“98”是 1998的返回值。getYear
在ECMAScript第3版中被getFullYear()
替代。IE修改了getYear()
,工做方式和 getFullYear()
类似,从而使其兼容Y2K,可是Mozilla仍保持标准的方式。
Different browsers execute JavaScript differently. For example, the following code assumes that the div
node already exists in the DOM by the time the script
block executes:
不一样的浏览器运行JavaScript时也不相同。好比,下面的代码假设在script
块执行以前,节点div
已经存于与DOM中:
... <div id="foo">Loading...</div> <script> document.getElementById("foo").innerHTML = "Done."; </script>
However, this is not guaranteed. To be sure that all elements exist, you should use the onload
event handler on the <body>
tag:
然而,这是没有保证的。要确保全部的元素都存在,用户应该在<body>
标签中使用onload
事件句柄(onload
event handler)。
<body onload="doFinish();"> <div id="foo">Loading...</div> <script> function doFinish() { var element = document.getElementById("foo"); element.innerHTML = "Done."; } </script> ...
Such timing-related issues are also hardware-related -- slower systems can reveal bugs that faster systems hide. One concrete example is window.open
, which opens a new window:
像这些和时间耗费相关的话题也是和硬件相关的--较慢的系统能够揭示出较快的系统中隐藏的bug。举个具体的例子,window.open
,它的功能是打开一个新的窗口:
<script> function doOpenWindow(){ var myWindow = window.open("about:blank"); myWindow.location.href = "http://www.ibm.com"; } </script>
The problem with the code is that window.open
is asynchronous -- it does not block the JavaScript execution until the window has finished loading. Therefore, you may execute the line after the window.open
line before the new window has finished. You can deal with this by having an onload
handler in the new window and then call back into the opener window (using window.opener
).
这段代码的问题在于,window.open
是异步执行的--它在这个窗体加载完成以前不会阻塞JavaScript的执行。所以, window.open
以后的代码有可能在新窗体加载完以前执行。用户能够用下面的方法解决这个问题:在新窗体中定义一个onload
handler,而后返回到父窗体(使用window.opener
)。
JavaScript can, through document.write
, generate HTML on the fly from a string. The main issue here is when JavaScript, embedded inside an HTML document (thus, inside an <script>
tag), generates HTML that contains a <script>
tag. If the document is in strict rendering mode, it will parse the </script>
inside the string as the closing tag for the enclosing <script>
. The following code illustrates this best:
经过document.write,JavaScript能够生成任意的HTML代码。这里的主要问题是,当JavaScript嵌在HTML文档(在 <script>
标签中)中,生成的HTML代码中包含<script>
会怎么样?若是文档(document)是strict rendering mode(严格的绘制模式),它会把字符串中的</script>
看成与<script>
对应的结束标签解析。下面的代码很好地说明了这种状况:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> ... <script> document.write("<script type='text\/javascript'>alert('Hello');<\/script>") </script>
Since the page is in strict mode, Mozilla's parser will see the first <script>
and parse until it finds a closing tag for it, which would be the first </script>
. This is because the parser has no knowledge about JavaScript (or any other language) when in strict mode. In quirks mode, the parser is aware of JavaScript when parsing (which slows it down). Internet Explorer is always in quirks mode, as it does not support true XHTML. To make this work in strict mode in Mozilla, separate the string into two parts:
由于页面处于strict mode,Mozella的解析器读到第一个<script>
,而后继续解析直到找到它的结束标签,那就是第一个</script>
。这是由于在strict mode下,解析器不懂得关于JavaScript(或者其余语言)的任何知识。quirks mode下,解析器在解析时会考虑JavaScript(这会使它变慢)。IE一直在quirks mode,所以它不支持真正地XHTML。为了让相似地代码能够在Mozilla地strict mode下工做,把那个字符串拆成两部分就能够了:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> ... <script> document.write("<script type='text\/javascript'>alert('Hello');</" + "script>") </script>
Mozilla provides several ways to debug JavaScript-related issues found in applications created for Internet Explorer. The first tool is the built-in JavaScript console, shown in Figure 1, where errors and warnings are logged. You can access it in Mozilla by going to Tools -> Web Development -> JavaScript Console or in Firefox (the standalone browser product from Mozilla) at Tools -> JavaScript Console.
Mozilla提供了几种方法,用于调试本来为IE编写的程序中与JavaScript相关的问题。第一个工具是Mozilla自带的 JavaScript console(见图1),在那里记录了错误(errors)和警告(warning)。要打开它,在Mozilla中,点击Tools -> Web Development -> JavaScript Console;在firefox中(卓越的Mozilla浏览器),点击 Tools -> JavaScript Console(译注:firefox2.0中是Tools->Error Console)。
Figure 1. JavaScript console
The JavaScript console can show the full log list or just errors, warnings, and messages. The error message in Figure 1 says that at aol.com, line 95 tries to access an undefined variable called is_ns70. Clicking on the link will open Mozilla's internal view source window with the offending line highlighted.
JavaScript console(或者Erroe console)能够显示完整的记录,或者只是错误、警告、信息 (errors, warnings, and messages)。图1中的错误信息说,在aol.com,95行试图去访问一个没有定义的变量is_ns70(at aol.com, line 95 tries to access an undefined variable called is_ns70)。单击该连接会打开Mozilla自带的源码查看窗口,高亮显示对应的代码行。 The console also allows you to evaluate JavaScript. To evaluate the entered JavaScript syntax, type in 1+1
into the input field and press Evaluate, as Figure 2 shows.
在console中也能够计算JavaScript表达式的值。要计算JavaScript表达式,在输入框中输入1+1
而后点击Evaluate(计算),如图2所示。
Figure 2. JavaScript console evaluating
Mozilla's JavaScript engine has built-in support for debugging, and thus can provide powerful tools for JavaScript developers. Venkman, shown in Figure 3, is a powerful, cross-platform JavaScript debugger that integrates with Mozilla. It is usually bundled with Mozilla releases; you can find it at Tools -> Web Development -> JavaScript Debugger. For Firefox, the debugger isn't bundled; instead, you can download and install it from the Venkman Project Page. You can also find tutorials at the development page, located at the Venkman Development Page.
Mozilla的JavaScript引擎内建了调试功能,这样就提供为JavaScript编写者提供了强有力的工具。图3中的Venkman,与 Mozilla集成,是一个功能强大、跨平台的JavaScript调试工具。它一般包含Mozilla的发行版本中,用户能够点击 Tools -> Web Development -> JavaScript Debugger找到它。对于Firefox,这个调试工具不是集成的;用户能够从Venkman Project Page下载并安装它。用户也会能够在Venkman Development Page找到用户指南。 Figure 3. Mozilla's JavaScript debugger
The JavaScript debugger can debug JavaScript running in the Mozilla browser window. It supports such standard debugging features as breakpoint management, call stack inspection, and variable/object inspection. All features are accessible through the user interface or through the debugger's interactive console. With the console, you can execute arbitrary JavaScript in the same scope as the JavaScript currently being debugged.
这个JavaScript调试工具能够调试正在Mozilla浏览器窗口中运行的JavaScript代码。它支持标准的调试功能,像断点管理、查看堆栈、查看变量/对象的值等。全部的调试功能,均可以经过界面或调试工具的命令行被用户使用。在JavaScript代码的调试过程当中,只要处于同一个做用域,用户就能够经过命令行运行任意的JavaScript代码。
Mozilla-based products have the strongest support for Cascading Style Sheets (CSS), including most of CSS1, CSS2.1 and parts of CSS3, compared to Internet Explorer as well as all other browsers.
与IE以及其余浏览器相比,基于Mozilla的产品对层叠样式表(CSS)提供了最好的支持,包括CSS一、CSS2的绝大部分和CSS3的一部分。
For most issues mentioned below, Mozilla will add an error or warning entry into the JavaScript console. Check the JavaScript console if you encounter CSS-related issues.
对于下文提到的不少问题,Mozilla会在JavaScript console中显示出error或warning项。若是用户碰到CSS方面的问题,能够去看看JavaScript console。
The most common CSS-related issue is that CSS definitions inside referenced CSS files are not applied. This is usually due to the server sending the wrong mimetype for the CSS file. The CSS specification states that CSS files should be served with the text/css
mimetype. Mozilla will respect this and only load CSS files with that mimetype if the Web page is in strict standards mode. Internet Explorer will always load the CSS file, no matter with which mimetype it is served. Web pages are considered in strict standards mode when they start with a strict doctype. To solve this problem, you can make the server send the right mimetype or remove the doctype. I'll discuss more about doctypes in the next section.
与CSS相关的问题中,最多见的就是被引用的CSS文件中的CSS定义不适用。这个问题一般是因为服务器给CSS文件发送了错误的 mimetype。CSS的规范中指出,CSS文件的mimetype应该为text/css。若是网页是strict standards mode,Mozilla会听从这个规范,而且只有在CSS文件的mimetype是text/css
时才加载该文件IE无论是那种mimetype,总 会加载CSS文件。网页只有以doctype开头,才被认为是strict standards mode。为了解决这个问题,用户可让服务器发送正确的mimetype,或者删除doctype。在下面的章节中,我将详细的讲解doctype。
译注:mime指多用途的网际邮件扩充协议。
Many Web applications do not use units with their CSS, especially when you use JavaScript to set the CSS. Mozilla tolerates this, as long as the page is not rendered in strict mode. Since Internet Explorer does not support true XHTML, it does not care if no units are specified. If the page is in strict standards mode, and no units are used, then Mozilla ignores the style:
不少网页应用程序在它们的CSS中都不使用度量单位,尤为是用户在JavaScript中设置CSS的时候。Mozilla对此很宽容,只要网页不 是在strict mode。由于IE不支持真正的XHTML,即便没有定义度量单位它也不会关心。若是网页是strict standards mode,而且没有使用度量单位,Mozilla将忽略这些样式:
<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>CSS and units example</title>
</head>
<body>
// works in strict mode
<div style="width: 40px; border: 1px solid black;">
Text
</div>
// will fail in strict mode
<div style="width: 40; border: 1px solid black;">
Text
</div>
</body>
</html>
Since the above example has a strict doctype, the page is rendered in strict standards mode. The first div will have a width of 40px, since it uses units, but the second div won't get a width, and thus will default to 100% width. The same would apply if the width were set through JavaScript.
上面的例子中有明确的doctype定义,因此该网页以 strict standards mode显示。(在显示的结果中)因为第一个div中使用了度量单位,因此它的宽度是40象素;但第二个div没有获取width的值,所以它的 width的值是默认的100%(译注:在firefox2.0中,默认值是40px)。若是width属性是经过JavaScript设置的,一样的事 也会发生。
Since Mozilla supports the CSS standards, it also supports the CSS DOM standard for setting CSS through JavaScript. You can access, remove, and change an element's CSS rules through the element's style
member:
由于Mozilla支持CSS标准,因此它也支持CSS DOM标准,能够经过JavaScript设置CSS。用户能够经过元素的style
成员读取、修改或删除元素的CSS规则:
<div id="myDiv" style="border: 1px solid black;"> Text </div> <script> var myElm = document.getElementById("myDiv"); myElm.style.width = "40px"; </script>
You can reach every CSS attribute that way. Again, if the Web page is in strict mode, you must set a unit or else Mozilla will ignore the command. When you query a value, say through .style.width
, in Mozilla and Internet Explorer, the returned value will contain the unit, meaning a string is returned. You can convert the string into a number through parseFloat("40px")
.
用户能够用一样的方法访问全部的CSS属性。再次提醒,若是网页是strict mode,用户必须设置度量单位,不然Mozilla将忽略这行代码。用户能够用 .style.width在Mozilla和IE中查询属性值,返回值是包含度量单位在内的,也就是说返回值是string(字符串)。用户能够用parseFloat("40px")
把string转换成数字。
// 捕获鼠标移动
mydiv.setCapture();
document.onmousemove = mydivMoveFunc;
// 释放鼠标移动
mydiv.releaseCapture();
document.onmousemove = null;
对于Firefox浏览器来讲,要这样处理:
// 捕获鼠标移动window.captureEvents(Event.MOUSEMOVE);
window.onmousemove = mydivMoveFunc;
// 释放鼠标移动
window.releaseEvents(Event.MOUSEMOVE);
window.onmousemove = null;
CSS added the notion of overflow, which allows you to define how to handle overflow; for example, when the contents of a div
with a specified height are taller than that height. The CSS standard defines that if no overflow behavior is set in this case, the div
contents will overflow. However, Internet Explorer does not comply with this and will expand the div
beyond its set height in order to hold the contents. Below is an example that shows this difference:
CSS中有overfolw(溢出)的标记,有了它,开发者能够本身决定如何处理overflow;好比,div
的内容的实际高度比div
定义的高 度高。CSS标准中的定义是,若是这种状况下没有设置overflow的处理代码,div
的内容将溢出。然而,IE并不听从这个定义,它为了显示所有内 容,会拉长这个div
,超出原来设置的高度。下面的例子能够说明这点差别:
<div style="height: 100px; border: 1px solid black;"> <div style="height: 150px; border: 1px solid red; margin: 10px;"> a </div> </div>
As you can see in Figure 4, Mozilla acts like the W3C standard specifies. The W3C standard says that, in this case, the inner div
overflows to the bottom since the inner content is taller than its parent. If you prefer the Internet Explorer behavior, simply do not specify a height on the outer element.
如图4所示,Mozilla按照W3C的规范处理。W3C标准说,在这种状况下,由于内div
(里面的那个div
)的内容高于外div
,因此内div
会溢出底部。若是用户喜欢IE的行为,在外div
中不定义高度就能够了。
Figure 4. DIV overflow
The nonstandard CSS hover behavior in Internet Explorer occurs on quite a few web sites. It usually manifests itself by changing text style when hovered over in Mozilla, but not in Internet Explorer. This is because the a:hover
CSS selector in Internet Explorer matches <a href="">...</a>
but not <a name="">...</a>
, which sets anchors in HTML. The text changes occur because authors encapsulate the areas with the anchor-setting markup:
在IE中,非标准的CSS hover行为只有在少数页面中才会发生。在Mozilla中,CSS hover通常会在(鼠标)掠过其上方时,改变颜色秀出本身,但在IE中不会。这是由于IE中a:hover
的CSS选择器匹配<a href="">...</a>
,但不匹配<a name="">...</a>
,后者是在HTML中设置anchor(锚点或锚记)。文本发生改变是由于做者用设置anchor的标记把这个区域包围了起来:
CSS: a:hover {color: green;} HTML: <a href="foo.com">This text should turn green when you hover over it.</a> <a name="anchor-name"> This text should change color when hovered over, but doesn't in Internet Explorer. </a>
Mozilla follows the CSS specification correctly and will change the color to green in this example. You can use two ways to make Mozilla behave like Internet Explorer and not change the color of the text when hovered over:
a:link:hover {color: green;}
, which will only change the color if the element is a link (has an href
attribute). <a />
before the start of the text -- the anchor will continue to work this way. Mozilla彻底听从CSS的规范,在本例中会把颜色变成绿色。用户有两种办法,可让Mozilla像IE同样,在鼠标掠过这段文字时不改变颜色:
a:link:hover {color: green;}
,这样,只有元素是超连接时(有href
属性),颜色才会改变。 <a />
--这样anchor能够保留原有的功能。 Older legacy browsers, such as Internet Explorer 4, rendered with so-called quirks under certain conditions. While Mozilla aims to be a standards-compliant browser, it has three modes that support older Web pages created with these quirky behaviors. The page's content and delivery determine which mode Mozilla will use. Mozilla will indicate the rendering mode in View -> Page Info (or Ctrl+I
) ; Firefox will list the rendering mode in Tools -> Page Info. The mode in which a page is located depends on its doctype.
较老的浏览器,如IE4,在一些特定的状况下,会用所谓的另类模式(quirks)显示页面。由于Mozilla的目标是一款支持标准的浏览器,因此它有三种模式,能够支持带有特有行为的老网页。页面的内容以及delvery决定着Mozilla使用那种模式。Mozilla能够用View -> Page Info (或 Ctrl+I
)指示显示模式;Firefox用Tools -> Page Info列出显示模式。页面处于哪一种模式由doctype(文档类型声明)决定。
Doctypes (short for document type declarations) look like this:
Doctype(document type declarations的缩写)以下所示:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
The section in blue is called the public identifier, the green part is the system identifier, which is a URI.
蓝色的部分是公有标识符;绿色的部分是系统标识符,它是个URI。
Standards mode is the strictest rendering mode -- it will render pages per the W3C HTML and CSS specifications and will not support any quirks. Mozilla uses it for the following conditions:
标准模式(standard mode)是最严格的显示模式——它将根据W3C HTML和CSS规范显示页面,而不支持任何特有行为。Mozilla在下面这些状况中使用该模式:
text/xml
mimetype or any other XML or XHTML mimetype <!DOCTYPE HTML SYSTEM "http://www.w3.org/TR/REC-html40/strict.dtd">
), except for the IBM doctype Mozilla introduced almost standards mode for one reason: a section in the CSS 2 specification breaks designs based on a precise layout of small images in table cells. Instead of forming one image to the user, each small image ends up with a gap next to it. The old IBM homepage shown in Figure 5 offers an example.
Mozilla引入了准标准模式(almost standards mode)是由于如下缘由:CSS2规范中的一节破坏了基于表格的小图片精确布局的设计。不一样于合成一张图片给用户,每张小图片以后都有一小段间隙。图5中的IBM旧首页就是一个例子。
图5. 图片间隙
Almost standards mode behaves almost exactly as standards mode, except when it comes to an image gap issue. The issue occurs often on standards-compliant pages and causes them to display incorrectly.
准标准模式的行为与标准模式极为接近,除了它碰到图片后有间隙的时候。这种状况经常在兼容标准的页面中发生,使页面显示不正确。
Mozilla uses almost standards mode for the following conditions:
在下面这些状况下中Mozilla使用准标准模式:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
, <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
) <!DOCTYPE html SYSTEM "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd">
) You can read more about the image gap issue.
读者能够阅读更多关于 图片间隙的话题。
Currently, the Web is full of invalid HTML markup, as well as markup that only functions due to bugs in browsers. The old Netscape browsers, when they were the market leaders, had bugs. When Internet Explorer arrived, it mimicked those bugs in order to work with the content at that time. As newer browsers came to market, most of these original bugs, usually called quirks, were kept for backwards compatibility. Mozilla supports many of these in its quirks rendering mode. Note that due to these quirks, pages will render slower than if they were fully standards-compliant. Most Web pages are rendered under this mode.
当前,互联网上有不少错误的HTML标记,也包括只有由于浏览器的bug才能起做用的标记。老版本的Netscape浏览器——当时市场的主流——是有bug的。当IE成为市场主流的时候,为了在当时能处理那些页面,它模仿了这些bug。当新的浏览器面世的时候,原来的大多数bug——一般被称做quirks——为了兼容性而被保留了下来。Mozilla在另类显示模式中支持不少这种页面。注意,因为这些“另类”,页面显示的速度比它们是标准页面时要慢。大多数网页都是以这种模式显示的。
Mozilla uses quirks mode for the following conditions:
在如下状况中,Mozilla使用另类模式:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
) For further reading, check out: Mozilla Quirks Mode Behavior and Mozilla's DOCTYPE sniffing.
要想了解更多,请阅读 Mozilla Quirks Mode Behavior和Mozilla's DOCTYPE sniffing。
Mozilla and Internet Explorer are almost completely different in the area of events. The Mozilla event model follows the W3C and Netscape model. In Internet Explorer, if a function is called from an event, it can access the event
object through window.event
. Mozilla passes an event
object to event handlers. They must specifically pass the object on to the function called through an argument. A cross-browser event handling example follows:
在事件(event)处理方面,能够说Mozilla与IE是彻底不一样。Mozilla的事件处理模型沿用了W3C和Netscape的模型。在IE中,若是函数被一个事件调用,它能够经过window.event
访问event
对象。而Mozilla把event
对象传递给事件句柄(event handler)。它们必须用不一样的参数把这个对象传递到函数中。跨浏览器的事件处理代码可能会写成这样:
<div onclick="handleEvent(event);">Click me!</div> <script> function handleEvent(aEvent) { // if aEvent is null, means the Internet Explorer event model, // so get window.event. var myEvent = aEvent ? aEvent : window.event; } </script>
Sometimes this doesn't work because Internet Explorer "catches" the aEvent parameter, identifiying it as not null, making it not use window.event any longer. The solution is to simply test for the window.event property:
但有时候这不会起做用,由于IE“捕获”这个aEvent参数,认为它不是空值,这样就使得window.event不会被用到。其实简单的解决办法是判断下window.event属性:
<div onclick="handleEvent(event);">Click me!</div> <script> function handleEvent(aEvent) { var myEvent = window.event ? window.event : aEvent; } </script>
The properties and functions that the event object exposes are also often named differently between Mozilla and Internet Explorer, as Table 4 shows.
Mozilla与IE中,事件属性和函数的名字一般是不同的,如表4所示:
Internet Explorer Name | Mozilla Name | Description |
---|---|---|
altKey | altKey | Boolean property that returns whether the alt key was pressed during the event. |
cancelBubble | stopPropagation() | Used to stop the event from bubbling farther up the tree. |
clientX | clientX | The X coordinate of the event, in relation to the element viewport. |
clientY | clientY | The Y coordinate of the event, in relation to the element viewport. |
ctrlKey | ctrlKey | Boolean property that returns whether the Ctrl key was pressed during the event. |
fromElement | relatedTarget | For mouse events, this is the element from which the mouse moved away. |
keyCode | keyCode | For keyboard events, this is a number representing the key that was pressed. It is 0 for mouse events. |
returnValue | preventDefault() | Used to prevent the event's default action from occurring. |
screenX | screenX | The X coordinate of the event, in relation to the screen. |
screenY | screenY | The Y coordinate of the event, in relation to the screen. |
offsetX | layerX | 获取鼠标在对像上X坐标. |
offsetY | layerY | 获取鼠标在对像上Y坐标. |
shiftKey | shiftKey | Boolean property that returns whether the Shift key was pressed during the event. |
srcElement | target | The element to which the event was originally dispatched. |
toElement | currentTarget | For mouse events, this is the element to which the mouse moved. |
type | type | Returns the name of the event. |
Mozilla supports two ways to attach events through JavaScript. The first, supported by all browsers, sets event properties directly on objects. To set a click
event handler, a function reference is passed to the object's onclick
property:
Mozilla有两种方法经过JavaScript添加event。第一种,也是全部浏览器都支持的,直接给对象(object)添加event属性。要设置一个click的event句柄,可使用函数的引用设置onclick属性:
<div id="myDiv">Click me!</div> <script> function handleEvent(aEvent) { // if aEvent is null, means the Internet Explorer event model, // so get window.event. var myEvent = aEvent ? aEvent : window.event; } function onPageLoad(){ document.getElementById("myDiv").onclick = handleEvent; } </script>
Mozilla fully supports the W3C standard way of attaching listeners to DOM nodes. You use the addEventListener()
and removeEventListener()
methods, and have the benefit of being able to set multiple listeners for the same event type. Both methods require three parameters: the event type, a function reference, and a boolean denoting whether the listener should catch events in their capture phase. If the boolean is set to false, it will only catch bubbling events. W3C events have three phases: capturing, at target, and bubbling. Every event object has an eventPhase
attribute indicating the phase numerically (0 indexed). Every time you trigger an event, the event starts at the DOM's outermost element, the element at the top of the DOM tree. It then walks the DOM using the most direct route toward the target, which is the capturing phase. When the event reaches the target, the event is in the target phase. After arriving at the target, it walks up the DOM tree back to the outermost node; this is bubbling. Internet Explorer's event model only has the bubbling phase; therefore, setting the third parameter to false results in Internet Explorer-like behavior:
Mozilla支持W3C标准定义的添加linstener给DOM节点的全部方法。用户可使用addEventListener()
和 removeEventListener()
函数,也能够向同一个event type(事件类型)添加多个listener。两个函数都须要三个参数:event type(事件类型),function reference(函数引用),和一个标识listener在捕获阶段(capture phase)是否捕获事件的boolean(布尔值)。若是boolean参数设为false,它将只捕获bubbling event。W3C对event定义了三个阶段:capturing,at target,和bubbling。每一个event对象都有eventPhase
属性,以数字代表所处的阶段(索引从0开始)。每当event被触发时,event从DOM最外层的元素(在DOM 树型结构最顶端的元素)开始,而后它沿着最短的路径向target(目标节点)遍历,这就是捕获阶段。当事件到达目标节点, 事件就转到目标节点阶段。到达目标节点以后,它就沿着DOM树上溯到最外层的节点;这个过程就是冒泡(bubling)。IE的事件模型(event model)只支持冒泡阶段,因此,把第三个参数设为false就会获得与IE的类似行为:
<div id="myDiv">Click me!</div> <script> function handleEvent(aEvent) { // if aEvent is null, it is the Internet Explorer event model, // so get window.event. var myEvent = aEvent ? aEvent : window.event; } function onPageLoad() { var element = document.getElementById("myDiv"); element.addEventListener("click", handleEvent, false); } </script>
One advantage of addEventListener()
and removeEventListener()
over setting properties is that you can have multiple event listeners for the same event, each calling another function. Thus, to remove an event listener requires all three parameters be the same as the ones you use when adding the listener.
和设置属性相比,addEventListener()和removeEventListener()的优点在于,对同一个event能够有多个 event listener,每个都是调用不一样的函数。所以,删除一个event listener时,要求三个参数与添加listener时的三个参数彻底相同。
Mozilla does not support Internet Explorer's method of converting <script> tags into event handlers, which extends <script> with for
and event
attributes (see Table 5). It also does not support the attachEvent
and detachEvent
methods. Instead, you should use the addEventListener
and removeEventListener
methods. Internet Explorer does not support the W3C events specification.
Mozilla不支持IE中把<script>标签转换为event handler的方法——IE用for和event属性对<script>进行了扩展(参加表5)。它用样不支持attachEvent和 detachEvent方法。用户应该使用addEventListener和removeEventListener方法。IE不支持W3C的 event规范。
Internet Explorer Method | Mozilla Method | Description |
---|---|---|
attachEvent(aEventType, aFunctionReference) | addEventListener(aEventType, aFunctionReference, aUseCapture) | Adds an event listener to a DOM element. |
detachEvent(aEventType, aFunctionReference) | removeEventListener(aEventType, aFunctionReference, aUseCapture) | Removes an event listener to a DOM element. |
While Mozilla prides itself with being the most W3C web standards compliant browser, it does support nonstandard functionality, such as innerHTML
and rich text editing, if no W3C equivalent exists.
在Mozilla做为对W3C web标准支持最好的浏览器的同时,它也支持非标准的功能,好比innerHTML
和富文本编辑rich text editing, 前提是没有相应的W3C规范。
Mozilla 1.3 introduced an implementation of Internet Explorer's designMode feature, which turns an HTML document into a rich text editor field. Once turned into the editor, commands can run on the document through the execCommand
command. Mozilla does not support Internet Explorer's contentEditable
attribute for making any widget editable. You can use an iframe to add a rich text editor.
Mozilla1.3引入了IE中designMode功能,它能够把HTML文档转换为富文本编辑区域 ,各类指令能够经过execCommand
命令在document中执行。Mozilla不支持IE中把全部控件都变为可编辑状态(editable)的contentEditable
属性。但用户能够用iframe添加富文本编辑。
Mozilla supports the W3C standard of accessing iframe's document object through IFrameElmRef.contentDocument
, while Internet Explorer requires you to access it through document.frames["IframeName"]
and then access the resulting document
:
Mozilla支持经过IFrameElmRef.contentDocument
访问iframe的document对象的W3C标准;而IE要求用户经过document.frames["IframeName"]
获取它,再访问结果中的document
。
<script> function getIFrameDocument(aID) { var rv = null; // if contentDocument exists, W3C compliant (Mozilla) if (document.getElementById(aID).contentDocument){ rv = document.getElementById(aID).contentDocument; } else { // IE rv = document.frames[aID].document; } return rv; } </script>
Another difference between Mozilla and Internet Explorer is the HTML that the rich text editor creates. Mozilla defaults to using CSS for the generated markup. However, Mozilla allows you to toggle between HTML and CSS mode using the useCSS
execCommand and toggling it between true and false. Internet Explorer always uses HTML markup.
Mozilla与IE间的另外一个差异是富文本编辑生成的HTML不一样。 Mozilla默认使用CSS标记。固然,Mozilla也容许用户在execCommand中用useCSS进行HTML与CSS模式的切换。而IE只使用HTML标记。
Mozilla (CSS): <span style="color: blue;">Big Blue</span> Mozilla (HTML): <font color="blue">Big Blue</font> Internet Explorer: <FONT color="blue">Big Blue</FONT>
Below is a list of commands that execCommand in Mozilla supports:
下面是Mozillla支持的execCommand命令的列表:
Command Name | Description | Argument |
---|---|---|
bold | Toggles the selection's bold attribute. | --- |
createlink | Generates an HTML link from the selected text. | The URL to use for the link |
delete | Deletes the selection. | --- |
fontname | Changes the font used in the selected text. | The font name to use (Arial, for example) |
fontsize | Changes the font size used in the selected text. | The font size to use |
fontcolor | Changes the font color used in the selected text. | The color to use |
indent | Indents the block where the caret is. | --- |
inserthorizontalrule | Inserts an <hr> element at the cursor's position. | --- |
insertimage | Inserts an image at the cursor's position. | URL of the image to use |
insertorderedlist | Inserts an ordered list (<ol>) element at the cursor's position. | --- |
insertunorderedlist | Inserts an unordered list (<ul>) element at the cursor's position. | --- |
italic | Toggles the selection's italicize attribute. | --- |
justifycenter | Centers the content at the current line. | --- |
justifyleft | Justifies the content at the current line to the left. | --- |
justifyright | Justifies the content at the current line to the right. | --- |
outdent | Outdents the block where the caret is. | --- |
redo | Redoes the previous undo command. | --- |
removeformat | Removes all formatting from the selection. | --- |
selectall | Selects everything in the rich text editor. | --- |
strikethrough | Toggles the strikethrough of the selected text. | --- |
subscript | Converts the current selection into subscript. | --- |
superscript | Converts the current selection into superscript. | --- |
underline | Toggles the underline of the selected text. | --- |
undo | Undoes the last executed command. | --- |
unlink | Removes all link information from the selection. | --- |
useCSS | Toggles the usage of CSS in the generated markup. | Boolean value |
For more information, visit Rich-Text Editing in Mozilla.
想了解更多信息,请参见Rich-Text Editing in Mozilla。
Mozilla has strong support for XML and XML-related technologies, such as XSLT and Web services. It also supports some nonstandard Internet Explorer extensions, such as XMLHttpRequest.
Mozilla对XML以及与XML相关的技术提供强有力的支持,好比XSLT和Web services。它也支持一些非标准的IE扩展,好比XMLHttpRequest。
(tick.huang@gmail.com end @ 2006.11.8)
As with standard HTML, Mozilla supports the W3C XML DOM specification, which allows you to manipulate almost any aspect of an XML document. Differences between Internet Explorer's XML DOM and Mozilla are usually caused by Internet Explorer's nonstandard behaviors. Probably the most common difference is how they handle white space text nodes. Often when XML generates, it contains white spaces between XML nodes. Internet Explorer, when using XMLNode.childNodes[]
, will not contain these white space nodes. In Mozilla, those nodes will be in the array.
就像支持标准的HTML同样,Mozilla一样支持W3C XML DOM的规范,这使用户能够对XML文档进行多种多样的操做。IE与Mozilla之间的XML DOM差别一般是有IE的非标准行为引发的。也许最多见的差别就是它们如何处理文本节点(译注:text node,指<... />或<...>...</....>以外的文件内容,包括空格、回车等)的空白符(译注:空格、制表符等)。一般,生成XML时,在XML节点间会有空白符。IE调用XMLNode.childNodes[]
时,在结果中不会包含这些是空白符的节点。而Mozilla中,这些空节点会在数组中。
XML: <?xml version="1.0"?> <myXMLdoc xmlns:myns="http://myfoo.com"> <myns:foo>bar</myns:foo> </myXMLdoc> JavaScript: var myXMLDoc = getXMLDocument().documentElement; alert(myXMLDoc.childNodes.length);
The first line of JavaScript loads the XML document and accesses the root element (myXMLDoc
) by retrieving the documentElement
. The second line simply alerts the number of child nodes. Per the W3C specification, the white spaces and new lines merge into one text node if they follow each other. For Mozilla, the myXMLdoc
node has three children: a text node containing a new line and two spaces; the myns:foo
node; and another text node with a new line. Internet Explorer, however, does not abide by this and will return "1" for the above code, namely only the myns:foo
node. Therefore, to walk the child nodes and disregard text nodes, you must distinguish such nodes.
第一行JavaScript代码加载XML document并经过documentElement
获取根元素(myXMLDoc
)。 第二行代码只是简单的显示子节点的个数。根据W3C规范,若是空格和回车相邻,它们将被合并成一个文本节点(text node)。对于Mozilla,myXMLdoc节点有三个子节点:第一个节点有一个回车和两个空格;第二个节点是myns:foo;第三个节点有一个 回车。而IE没有遵照这个规范,上面的这段代码将返回“1”,也就是说只有myns:foo节点。因此,遍历子节点以及是否忽略文本节点(text node),用户须要区分对待。
As mentioned earlier, every node has a nodeType
attribute representing the node type. For example, an element node has type 1, while a document node has type 9. To disregard text nodes, you must check for types 3 (text node) and 8 (comment node).
在前面已经提过,每一个节点有个nodeType属性标识节点的类型。好比,元素节点(element node)的类型是1,文档节点(document node)的类型是9。要忽略text node,须要判断类型3(文本节点)和8(注释节点)。
XML: <?xml version="1.0"?> <myXMLdoc xmlns:myns="http://myfoo.com"> <myns:foo>bar</myns:foo> </myXMLdoc> JavaScript: var myXMLDoc = getXMLDocument().documentElement; var myChildren = myXMLDoc.childNodes; for (var run = 0; run < myChildren.length; run++){ if ( (myChildren[run].nodeType != 3) && myChildren[run].nodeType != 8) ){ // 不是文本节点或注释节点 }; };
Internet Explorer has a nonstandard feature called XML data islands, which allow you to embed XML inside an HTML document using the nonstandard HTML tag <xml>
. Mozilla does not support XML data islands and handles them as unknown HTML tags. You can achieve the same functionality using XHTML; however, because Internet Explorer's support for XHTML is weak, this is usually not an option.
IE有个非标准的特性,被称为XML data islands,它容许用户在HTML文档中使用HTML的标记<xml>
嵌入XML。Mozilla不支持XML data island,就把它看成未知的HTML标记来处理。 用户可使用XHTML实现相同的功能;可是,由于IE对XHTML的支持比较弱,因此一般不推荐这种方法。
One cross-browser solution is to use DOM parsers, which parse a string that contains a serialized XML document and generates the document for the parsed XML. Mozilla uses the DOMParser
class, which takes the serialized string and creates an XML document out of it. In Internet Explorer, you can achieve the same functionality using ActiveX. A new Microsoft.XMLDOM
generates and has a loadXML
method that can take in a string and generate a document from it. The following code shows you how:
一个跨浏览器的解决办法是使用DOM解析器,它能够解析内容是序列化的(serialized)XML文档的string,而后生成文档。 Mozilla使用DOMParser
类,它以序列化的string做为输入,生成XML文档。在IE中,用户可使用ActiveX实现相同的功能。Microsoft.XMLDOM
有个方法loadXML
,它以string做为输入,生成文档。下面的代码演示了如何实现:
IE XML data island: .. <xml id="xmldataisland"> <foo>bar</foo> </xml> Cross-browser solution: var xmlString = "<xml id=\"xmldataisland\"><foo>bar</foo></xml>"; var myDocument; if (document.implementation.createDocument){ // Mozilla,建立DOMParser var parser = new DOMParser(); myDocument = parser.parseFromString(xmlString, "text/xml"); } else if (window.ActiveXObject){ // IE,用ActiveX建立XML document,而后把loadXML看成DOM解析器来用 myDocument = new ActiveXObject("Microsoft.XMLDOM"); myDocument.async="false"; myDocument.loadXML(xmlString); }
Internet Explorer allows you to send and retrieve XML files using MSXML's XMLHTTP
class, which is instantiated through ActiveX using new ActiveXObject("Msxml2.XMLHTTP")
or new ActiveXObject("Microsoft.XMLHTTP")
. Since there is no standard method of doing this, Mozilla provides the same functionality in the global JavaScript XMLHttpRequest
object. The object generates asynchronous requests by default.
IE容许用户使用MSXML的XMLHTTP
类发送和接受XML文件,这个类经过调用new ActiveXObject("Msxml2.XMLHTTP")
或new ActiveXObject("Microsoft.XMLHTTP")
进行实例化。由于不存在具备此功能的标准函数,因此Mozilla在全局的JavaScript对象XMLHttpRequest
中提供了相同的功能。该对象默认生成异步的请求。
After instantiating the object using new XMLHttpRequest()
, you can use the open
method to specify what type of request (GET or POST) you use, which file you load, and if it is asynchronous or not. If the call is asynchronous, then give the onload
member a function reference, which is called once the request has completed.
使用new XMLHttpRequest()
实例化对象后,用户可使用open
函数指定请求的类型(GET或POST)、要加载的文件、以及是否为异步调用。若是是异步调用,须要给onload
成员一个函数引用,请求一完成,这个函数就会被调用。
同步请求:
var myXMLHTTPRequest = new XMLHttpRequest(); myXMLHTTPRequest.open("GET", "data.xml", false); myXMLHTTPRequest.send(null); var myXMLDocument = myXMLHTTPRequest.responseXML;
异步请求:
var myXMLHTTPRequest; function xmlLoaded() { var myXMLDocument = myXMLHTTPRequest.responseXML; } function loadXML(){ myXMLHTTPRequest = new XMLHttpRequest(); myXMLHTTPRequest.open("GET", "data.xml", true); myXMLHTTPRequest.onload = xmlLoaded; myXMLHTTPRequest.send(null); }
Table 7 features a list of available methods and properties for Mozilla's XMLHttpRequest
.
表7列出了Mozilla的XMLHttpRequest
全部方法和属性。
Name | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
void abort() | Stops the request if it is still running. | ||||||||||||
string getAllResponseHeaders() | Returns all response headers as one string. | ||||||||||||
string getResponseHeader(string headerName) | Returns the value of the specified header. | ||||||||||||
functionRef onerror | If set, the references function will be called whenever an error occurs during the request. | ||||||||||||
functionRef onload | If set, the references function will be called when the request completes successfully and the response has been received. Use when an asynchronous request is used. | ||||||||||||
void open (string HTTP_Method, string URL) void open (string HTTP_Method, string URL, boolean async, string userName, string password) |
Initializes the request for the specified URL, using either GET or POST as the HTTP method. To send the request, call the send() method after initialization. If async is false, the request is synchronous, else it defaults to asynchronous. Optionally, you can specify a username and password for the given URL needed. |
||||||||||||
int readyState | State of the request. Possible values:
|
||||||||||||
string responseText | String containing the response. | ||||||||||||
DOMDocument responseXML | DOM Document containing the response. | ||||||||||||
void send(variant body) | Initiates the request. If body is defined, it issent as the body of the POST request. body can be an XML document or a string serialized XML document. |
||||||||||||
void setRequestHeader (string headerName, string headerValue) | Sets an HTTP request header for use in the HTTP request. Has to be called after open() is called. |
||||||||||||
string status | The status code of the HTTP response. |
Mozilla supports XSL Transformations (XSLT) 1.0. It also allows JavaScript to perform XSLT transformations and allows running XPATH on a document.
Mozilla支持XSLT 1.0( XSL Transformations)。它也容许JavaScript执行XSLT转换,和对document运行XPATH。
Mozilla requires that you send the XML and XSLT file holding the stylesheet with an XML mimetype (text/xml
or application/xml
). This is the most common reason why XSLT won't run in Mozilla but will in Internet Explorer. Mozilla is strict in that way.
Mozilla要求用户发送含有stylesheet的XML和XSLT文件时要有mimetype XML(text/xml or application/xml)。Mozilla对此要求很严格。这就是为何XSLT不能在Mozilla中运行而能在IE中运行的最多见的缘由。
Internet Explorer 5.0 and 5.5 supported XSLT's working draft, which is substantially different than the final 1.0 recommendation. The easiest way to distinguish what version an XSLT file was written against is to look at the namespace. The namespace for the 1.0 recommendation is http://www.w3.org/1999/XSL/Transform
, while the working draft's namespace is http://www.w3.org/TR/WD-xsl
. Internet Explorer 6 supports the working draft for backwards compatibility, but Mozilla does not support the working draft, only the final recommendation.
IE5.0和5.5支持XSLT的工做草案(working draft),这个工做草案和1.0最终推荐版(final 1.0 recommendation)之间有很大的差别。区分XSLT文件版本的最简单的方法是查看命名空间(namespace)。1.0推荐版的命名空间是http://www.w3.org/1999/XSL/Transform
,而working draft的命名空间是http://www.w3.org/TR/WD-xsl
。 IE6为了兼容性,支持工做草案;可是Mozilla不支持工做草案,它只支持最终推荐版。
If XSLT requires you to distinguish the browser, you can query the "xsl:vendor" system property. Mozilla's XSLT engine will report itself as "Transformiix" and Internet Explorer will return "Microsoft."
若是XLST要求用户区分浏览器,用户能够查询系统属性“xsl:vendor”。Mozilla的XLST引擎会报告说它本身是“transformiix”,而IE将返回“Microsoft”。
<xsl:if test="system-property('xsl:vendor') = 'Transformiix'"> <!-- Mozilla specific markup --> </xsl:if> <xsl:if test="system-property('xsl:vendor') = 'Microsoft'"> <!-- Internet Explorer specific markup --> </xsl:if>
Mozilla also provides JavaScript interfaces for XSLT, allowing a Web site to complete XSLT transformations in memory. You can do this using the global XSLTProcessor
JavaScript object. XSLTProcessor
requires you to load the XML and XSLT files, because it needs their DOM documents. The XSLT document, imported by the XSLTProcessor
, allows you to manipulate XSLT parameters. XSLTProcessor
can generate a standalone document using transformToDocument()
, or it can create a document fragment using transformToFragment()
, which you can easily append into another DOM document. Below is an example:
Mozilla提供了JavaScript接口,容许网站在内存中完成XSLT的转换。用户可使用全局的JavaScript对象XSLTProcessor
。XSLTProcessor
要求用户机咱XML和XSLT文件,由于它须要它们的DOM document。由XSLTProcessor
加载(import)的XSLT document容许用户对XSLT参数进行操做。XSLTProcessor
能够经过transformToDocument()
生成独立的document,它也能经过 transformToFragment()
生成document fragment,这让用户能够很方便地将其添加到别的DOM document。下面举个例子:
var xslStylesheet; var xsltProcessor = new XSLTProcessor(); // 加载xslt文件“example1.xsl” var myXMLHTTPRequest = new XMLHttpRequest(); myXMLHTTPRequest.open("GET", "example1.xsl", false); myXMLHTTPRequest.send(null); // 获取XML cocument并加载它 xslStylesheet = myXMLHTTPRequest.responseXML; xsltProcessor.importStylesheet(xslStylesheet); // 加载xmlwenj“example1.xml” myXMLHTTPRequest = new XMLHttpRequest(); myXMLHTTPRequest.open("GET", "example1.xml", false); myXMLHTTPRequest.send(null); var xmlSource = myXMLHTTPRequest.responseXML; var resultDocument = xsltProcessor.transformToDocument(xmlSource);
After creating an XSLTProcessor
, you load the XSLT file using XMLHttpRequest
. The XMLHttpRequest's responseXML
member contains the XML document of the XSLT file, which is passed to importStylesheet
. You then use the XMLHttpRequest
again to load the source XML document that must be transformed; that document is then passed to the transformToDocument
method of XSLTProcessor
. Table 8 features a list of XSLTProcessor
methods.
建立XSLTProcessor
以后,用户就能够用XMLHttpRequest()加载XSLT文件。XMLHttpRequest
的成员变量responseXML
的内容是对应这个XSLT文件的XML document,其中responseXML被传递给importStylesheet
。以后用户再次使用XMLHttpRequest
加载须要转换的XML文件,而后该文件被传递给XSLTProcessor
的transformToDocument
函数。表8列出了XSLTProcessor的函数。
Method | Description |
---|---|
void importStylesheet(Node styleSheet) | Imports the XSLT stylesheet. The styleSheet argument is the root node of an XSLT stylesheet's DOM document. |
DocumentFragment transformToFragment(Node source, Document owner) | Transforms the Node source by applying the stylesheet imported using the importStylesheet method and generates a DocumentFragment. owner specifies what DOM document the DocumentFragment should belong to, making it appendable to that DOM document. |
Document transformToDocument(Node source) | Transforms the Node source by applying the stylesheet imported using the importStylesheet method and returns a standalone DOM document. |
void setParameter(String namespaceURI, String localName, Variant value) | Sets a parameter in the imported XSLT stylesheet. |
Variant getParameter(String namespaceURI, String localName) | Gets the value of a parameter in the imported XSLT stylesheet. |
void removeParameter(String namespaceURI, String localName) | Removes all set parameters from the imported XSLT stylesheet and makes them default to the XSLT-defined defaults. |
void clearParameters() | Removes all set parameters and sets them to defaults specified in the XSLT stylesheet. |
void reset() | Removes all parameters and stylesheets. |