`
lovelium
  • 浏览: 18889 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
社区版块
存档分类
最新评论

把应用程序从 Internet Explorer 迁移到 Mozilla

阅读更多

级别: 初级

Doron Rosenberg (doronr@us.ibm.com), 助理软件工程师, IBM

2006 年 12 月 28 日

使 特定于 Internet Explorer 的 Web 应用程序在 Mozilla 上运行时,您遇到过麻烦吗?本文讨论了将应用程序迁移到基于开源 Mozilla 浏览器上时的常见问题。首先讨论跨浏览器开发的基本技术,然后介绍克服 Mozilla 和 Internet Explorer 之间差异的策略。

Netscape 最初开发 Mozilla 浏览器的时候,明智地决定支持 W3C 标准。因此,Mozilla 和 Netscape Navigator 4.x 以及 Microsoft Internet Explorer 遗留代码不完全向后兼容,比如后面将提到 Mozilla 不支持 <layer>。Internet Explorer 4 这些在 W3C 标准的概念出现之前建立的浏览器继承了很多古怪之处。本文中将讨论 Mozilla 的特殊模式,它为 Internet Explorer 和其他遗留浏览器提供了强大的 HTML 向后兼容功能。

我还将讨论 Mozilla 支持的非标准技术,如 XMLHttpRequest 和富文本编辑,因为当时 W3C 还没有对应的标准。其中包括:

通用的跨浏览器编码技巧

虽然存在 Web 标准,但不同浏览器的行为并不完全相同(实际上同一个浏览器在不同的平台上行为也不相同)。很多浏览器,如 Internet Explorer 依然支持 W3C 之前的、从未在 W3C 符合浏览器中获得广泛支持的 API。

深入讨论 Mozilla 和 Internet Explorer 的区别之前,首先介绍一下使 Web 应用程序具备可扩展性以便日后增加新浏览器支持的一些基本方法。

因为不同的浏览器有时会为同样的功能使用不同的 API,因此经常会在代码中看到很多 if() else() 块,来区别对待不同的浏览器。下面的代码块用于 Internet Explorer:

 
. . .

var elm;

if (ns4)
elm = document.layers["myID"];
else if (ie4)
elm = document.all["myID"];

上述代码不具备可扩展性,如果需要支持新的浏览器,必须修改 Web 应用程序中所有这样的代码块。

避免为新浏览器重新编码最简单的办法就是抽象功能。不要使用层层嵌套的 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

虽然使用用户代理来嗅探浏览器提供了所用浏览器的详细信息,但是出现新的浏览器版本时处理用户代理的代码可能出错,因而需要修改代码。

如果浏览器的类型无关紧要(假设禁止不支持的浏览器访问 Web 应用程序),最好通过浏览器本身的能力来嗅探。一般可以通过测试需要的 JavaScript 功能来完成。比如,与其使用:

 
if (isMozilla || isIE5)

不如用:

 
if (document.getElementById)

这样不用任何修改,在其他支持该方法的浏览器如 Opera 或 Safari 上也能工作。

但是如果准确性很重要,比如要验证浏览器是否满足 Web 应用程序的版本要求或者尝试避免某个 bug,则必须使用用户代理嗅探。

JavaScript 还允许使用内嵌条件语句,有助于提高代码的可读性:

 
var foo = (condition) ? conditionIsTrue : conditionIsFalse;

比如,要检索一个元素,可以用如下代码:

 
function getElement(aID){
return (document.getElementById) ? document.getElementById(aID)
: document.all[aID];
}





回页首


Mozilla 和 Internet Explorer 的区别

首先讨论 Mozilla 和 Internet Explorer 在 HTML 行为方式上的区别。

工具提示

遗留浏览器在 HTML 中引入了工具提示,在链接上显示 alt 属性作为工具提示的内容。最新的 W3C HTML 规范增加了 title 属性,用于包含链接的详细说明。现代浏览器应该使用 title 属性显示工具提示,Mozilla 仅支持用该属性显示工具提示而不能用 alt 属性。

实体

HTML 标记可以包含多种实体,W3 标准体 专门作了规定。可以通过数字或者字符引用来引用这些实体。比如,可以用 #160 或者等价的字符引用 &nbsp; 来引用空白字符  

一些旧式浏览器,如 Internet Explorer,有一些怪异的地方,比如允许用正常文本内容替换实体后面的分号(;):

 
&nbsp Foo
&nbsp&nbsp Foo

Mozilla 将把上面的 &nbsp 呈现为空格,虽然违反了 W3C 规范。如果后面紧跟着更多字符,浏览器就不能解析 &nbsp,如:

 
&nbsp12345

这样的代码在 Mozilla 中无效,因为违反了 W3 标准。为了避免浏览器的差异,应坚持使用正确的形式(&nbsp;)。





回页首


DOM 差异

文 档对象模型(DOM)是包含文档元素的树状结构。可以通过 JavaScript API 来操纵它,对此 W3C 已有标准。但是在 W3C 标准化之前,Netscape 4 和 Internet Explorer 4 以类似的方式实现了这种 API。Mozilla 仅实现了 W3C 标准不支持的那些遗留 API。

访问元素

未按照跨浏览器的方式检索元素的引用,应使用 document.getElementById(aID),该方法可用于 Internet Explorer 5.5+、Mozilla,是 DOM Level 1 规范的一部分。

Mozilla 不支持通过 document.elementName 甚至按照元素名来访问元素,而 Internet Explorer 则支持这种方法(也称为全局名称空间污染)。Mozilla 也不支持 Netscape 4 的 document.layers 方法和 Internet Explorer 的 document.all 方法。除了 document.getElementById 可以检索元素之外,还可用 document.layersdocument.all 获得具有特定标签名称的全部文档元素列表,比如所有的 <div> 元素。

W3C DOM Level 1 使用 getElementsByTagName() 方法获得所有相同标签名的元素的引用。该方法在 JavaScript 中返回一个数组,可用于 document 元素,也可用于其他节点只检索对应的子树。要获得 DOM 树中所有元素的列表,可使用 getElementsByTagName(*)

表 1 中列出了 DOM Level 1 方法,大部分用于把元素移动到特定位置或切换其可视性(菜单、动画)。Netscape 4 使用 <layer> 标签(Mozilla 不支持)作为可以任意定位的 HTML 元素。在 Mozilla 中,可使用 <div> 标签定位元素,Internet Explorer 也用它,HTML 规范中也包含它。

表 1. 用于访问元素的方法

方法 说明
document.getElementById( aId ) 返回具有指定 ID 的元素的引用。
document.getElementsByTagName( aTagName ) 返回文档中具有指定名称的元素数组。

遍历 DOM

Mozilla 通过 JavaScript 支持遍历 DOM 树的 W3C DOM API(如表 2 所示)。文档中每个节点都可使用这些 API 方法,可以在任何方向上遍历树。Internet Explorer 也支持这些 API,还支持原来用于遍历 DOM 树的 API,比如 children 属性。

表 2. 用于遍历 DOM 的方法

属性/方法 说明
childNodes 返回元素所有子节点的数组。
firstChild 返回元素的第一个子节点。
getAttribute( aAttributeName ) 返回指定属性的值。
hasAttribute( aAttributeName ) 返回一个 Boolean 值表明当前节点是否包含指定名称的属性。
hasChildNodes() 返回一个布尔指表明当前节点是否有子节点。
lastChild 返回元素的最后一个子节点。
nextSibling 返回紧接于当前节点之后的节点。
nodeName 用字符串返回当前节点的名称。
nodeType 返回当前节点的类型。

说明
1 元素节点
2 属性节点
3 文本节点
4 CDATA 选择节点
5 实体引用节点
6 实体节点
7 处理指令节点
8 注释节点
9 文档节点
10 文档类型节点
11 文档片断节点
12 符号节点
nodeValue 返回当前节点的值。对于包含文本的节点,如文本和注释节点返回其字符串值。对于属性节点返回属性值。其他节点返回 null
ownerDocument 返回包含当前节点的 document 对象。
parentNode 返回当前节点的父节点。
previousSibling 返回当前节点之前的相邻节点。
removeAttribute( aName ) 从当前节点中删除指定的属性。
setAttribute( aName, aValue ) 设置指定属性的值。

Internet Explorer 有一种非标准的特殊行为,这些 API 很多跳过(比如)新行字符生成的空白文本节点。Mozilla 则不跳过,因此有时候需要区分这些节点。每个节点都有一个 nodeType 属性指定了节点类型。比如,元素节点类型是 1,文本节点是 3,而注释节点是 8。仅处理元素节点最好的办法是遍历所有子节点,然后处理那些 nodeType 为 1 的节点:

 
HTML:
<div id="foo">
<span>Test</span>
c </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 支持向 DOM 动态增加内容的遗留方法,如 document.writedocument.opendocument.close。Mozilla 也支持 Internet Explorer 的 InnerHTML 方法,该方法基本上可以在任何节点上使用。但是不支持 OuterHTML(围绕着元素添加标记,标准中也没有等价的方法)和 innerText(设置节点的文本值,在 Mozilla 中可使用 textContent)。

Internet Explorer 有一些非标准的、Mozilla 不支持的内容操作方法,包括检索值、插入文本以及邻近某个节点插入元素,比如 getAdjacentElementinsertAdjacentHTML。表 3 说明了 W3C 标准和 Mozilla 操纵内容的方法,这些方法适用于任何 DOM 节点。

表 3. Mozilla 用于操纵内容的方法

方法 说明
appendChild( aNode ) 创建新的子节点。返回新建子节点的引用。
cloneNode( aDeep ) 创建调用节点的副本并返回。如果 aDeep 为 true,则复制该节点的整个子树。
createElement( aTagName ) 创建并返回一个 aTagName 指定类型的无父 DOM 节点。
createTextNode( aTextValue ) 创建并返回一个新的无父 DOM 文本节点,值由 aTextValue 指定。
insertBefore( aNewNode, aChildNode ) 在 aChildNode 前插入 aNewNode,前者必须是当前节点的子节点。
removeChild( aChildNode ) 删除 aChildNode 并返回对它的引用。
replaceChild( aNewNode, aChildNode ) 用 aNewNode 替换 aChildNode 并返回被删除节点的引用。

文档片断

出于性能方面的原因,可以在内存中创建文档而不是处理已有文档的 DOM。DOM Level 1 Core 引入了文档片断,这是一种轻型文档包含一般文档接口的一个子集。比如没有 getElementById 但是有 appendChild。很容易向已有文档添加文档片断。

Mozilla 使用 document.createDocumentFragment() 创建文档片断,该方法返回一个空的文档片断。

但是,Internet Explorer 的文档片断实现没有遵循 W3C 标准,仅仅返回一般的文档。





回页首


JavaScript 差异

Mozilla 和 Internet Explorer 的多数差异都和 JavaScript 有关。但问题通常源自浏览器向 JavaScript 公开的 API,比如 DOM 钩子。两种浏览器在核心 JavaScript 上区别不大,遇到的问题通常和时间有关。

JavaScript date 差异

Date 惟一的区别是 getYear 方法。根据 ECMAScript 规范(这是 JavaScript 所遵循的规范),该方法没有解决千年问题,在 2004 年运行 new Date().getYear() 将返回“104”。根据 ECMAScript 规范,getYear 返回的年份减去 1900 最初是为了在 1998 年返回“98”。ECMAScript Version 3 废止了 getYear,用 getFullYear() 代替。Internet Explorer 修改了 getYear() 使其和 getFullYear() 类似,消除了千年问题,而 Mozilla 坚持采用标准的行为方式。

JavaScript 执行差异

不同的浏览器执行 JavaScript 的方式是不同的。比如,下列代码假设 script 块执行的时候 div 节点已经存在于 DOM 中:

 
...
<div id="foo">Loading...</div>

<script>
document.getElementById("foo").innerHTML = "Done.";
</script>

但是并不能保证这一点。为了保证所有的元素已经存在,应该对 <body> 元素使用 onload 事件处理程序:

 
<body onload="doFinish()">

<div id="foo">Loading...</div>

<script>
function doFinish() {
var element = document.getElementById("foo");
element.innerHTML = "Done.";
}
</script>
...

这类与时间有关的问题也和硬件有关,速度慢的系统可能会发现速度快的系统隐藏起来的 bug。一个具体的例子是 window.open,它打开新的窗口:

 
<script>
function doOpenWindow(){
var myWindow = window.open("about:blank");
myWindow.location.href = "http://www.ibm.com";
}
</script>

这段代码的问题在于 window.open 是异步的,在窗口打开之前没有阻塞 JavaScript 的执行。因此,window.open 后面的行有可能在新窗口打开之前执行。可以在新窗口的 onload 处理程序中解决这个问题,然后回调打开它的窗口(使用 window.opener)。

JavaScript 生成 HTML 的差别

JavaScript 可以通过 document.write 即时用字符串生成 HTML。主要的问题在于,如果内嵌在 HTML 文档(因此也在一个 <script> 标签中)的 JavaScript 生成的 HTML 又包含 <script> 标签怎么办。如果文档采用 严格呈现模式,就会把字符串中的 </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>alert("Hello")</script>")
</script>

由于该页面采用严格模式,Mozilla 解析器就会看到第一个 <script> 并解析它直到发现第一个结束标签,即第一个 </script> 。这是因为解析器不知道 JavaScript(或者其他任何语言)何时采用严格模式。在特殊模式下,解析器在解析的过程中分析 JavaScript(因而降低了速度)。Internet Explorer 总是采用特殊模式,因此不真正支持 XHTML。为了在 Mozilla 中使用严格模式,需要将字符串分解成两部分:

 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
...
<script>
document.write("<script>alert("Hello")</" + "script>")
</script>

调试 JavaScript

Mozilla 提供了多种方法调试为 Internet Explorer 创建的应用程序中的 JavaScript 相关问题。第一个工具是内置的 JavaScript 控制台,如图 1 所示,它记录了错误和警告信息。在 Mozilla 中选择 Tools -> Web Development -> JavaScript Console,或者在 Firefox(来自 Mozilla 的独立浏览器产品)中选择 Tools -> JavaScript Console 就能打开它。


图 1. JavaScript 控制台
JavaScript 控制台

JavaScript 控制台可以显示完整的日志列表,也可以分别显示错误、警告和消息。图 1 中的错误消息表明,aol.com 第 95 行访问的变量 is_ns70 不存在。单击该链接可以打开 Mozilla 内部的查看源代码窗口,突出显示出错的一行。

控制台还允许对 JavaScript 求值。要计算输入的 JavaScript 语法,在输入字段中输入 1+1 然后按 Evaluate,结果如图 2 所示。


图 2. JavaScript 控制台求值
JavaScript 控制台求值

Mozilla 的 JavaScript 引擎内建了对调试的支持,从而为 JavaScript 开发人员提供了强大的工具。图 3 所示的 Venkman 是一种强大的跨平台 JavaScript 调试器,它与 Mozilla 集成在一起。它通常和 Mozilla 发行包捆绑在一起,可以通过选择 Tools -> Web Development -> JavaScript Debugger 打开它。Firefox 没有捆绑这个调试器,但是可以从 http://www.mozilla.org/projects/venkman/ 下载安装。还可以在开发页面上找到相关教程,开发页面的 URL 为 http://www.hacksrus.com/~ginda/venkman/


图 3. Mozilla 的 JavaScript 调试器
Mozilla 的 JavaScript 调试器

JavaScript 调试器可以调试在 Mozilla 浏览器窗口中运行的 JavaScript。它支持断点管理、查看调用栈和变量/对象检查这样的标准调试特性。所有特性都可通过用户界面或者调试器的交互控制台来访问。通过控 制台,可以在和调试的 JavaScript 代码同一作用域内执行任何 JavaScript。





回页首


CSS 差异

和 Internet Explorer 及其他浏览器相比,Mozilla 对级联样式表(CSS)的支持是最好的,包括 CSS1、CSS2 的全部和 CSS3 的一部分。

对于下面提到的多数问题,Mozilla 都会在 JavaScript 控制台中添加错误或警告记录。如果遇到和 CSS 有关的问题请检查 JavaScript 控制台。

Mimetypes(如果未应用 CSS 文件)

与 CSS 有关的最常见的问题就是:未应用所引用的 CSS 文件中的 CSS 定义。这通常是因为服务器为 CSS 文件提供了错误的 mimetype。CSS 规范指出,CSS 文件的 MIME 类型应该是 text/css。Mozilla 遵守这一点,在严格标准模式下只有这种 MIME 类型的 CSS 文件才会被加载。Internet Explorer 总是加载 CSS 文件,无论使用什么 mimetype。如果以严格的文档类型开始,则该网页被认为是严格标准模式。为了解决这个问题,可以让服务器发送正确的 mimetype 或者删除文档类型。下一节将进一步讨论文档类型。

CSS 和单位

很 多 Web 应用程序没有在 CSS 中使用单位,尤其是如果使用 JavaScript 设置 CSS。Mozilla 允许这样做,只要页面不以严格模式呈现。因为 Internet Explorer 不支持真正的 XHTML,没有指定单位也不必担心。如果页面处于严格标准模式而没有使用单位,则 Mozilla 将忽略该样式:

 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<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>

因为上面的例子使用了严格的文档类型,页面以严格标准模式呈现。第一个 div 的宽度为 40px,因为使用了单位;但是第二个 div 没有设置宽度,因此使用默认值 100%。如果通过 JavaScript 设置宽度,情况也是一样。

JavaScript 和 CSS

因为 Mozilla 支持 CSS 标准,它也支持通过 JavaScript 设置 CSS 的 CSS DOM 标准。可以通过元素的 style 成员访问、删除和修改元素的 CSS 规则:

 
<div id="myDiv" border:1px solid black;">
Text
</div>

<script>
var myElm = document.getElementById("myDiv");
myElm.style.width = "40px";
</script>

通过这种方法可以访问每一个 CSS 属性。同样,如果网页采用严格模式,就必须设置单位,否则 Mozilla 将忽略该命令。

在 Mozilla 和 Internet Explorer 中查询一个值,比如说 .style.width,返回值也包含单位,就是说是一个字符串。可用 parseFloat("40px") 将字符串转换成数字。

CSS 溢出的区别

CSS 增加了溢出的概念,允许定义如何处理溢出;比如,如果指定高度的 div 的实际高度超出的时候。 height.CSS 标准规定如果这种情况下没有定义溢出行为,则 div 内容就会溢出。但是,Internet Explorer 没有遵循这一点,而是扩展 div 的高度以便容纳其内容。下面的例子说明了这种差异:

 
<div style="height:100px; border: 1px solid black;">
<div style="height:150px; border: 1px solid red;
margin:10px;">
a
</div>
</div>

从图 4 可以看出,Mozilla 是按照标准规定处理的。标准规定,这种情况下内层的 div 溢出到底线,因为内层的内容比外层元素还高。如果愿意采用 Internet Explorer 的方式,只要不指定外层元素的高度即可。


图 4. DIV 溢出
DIV 溢出

悬停差异

Internet Explorer 的非标准 CSS 悬停行为出现在很多 IBM 网站上。Mozilla 中悬停的时候一般通过改变文本样式来表明自身,但是 Internet Explorer 没有这种行为。这是因为 a:hover CSS 选择器在 Internet Explorer 中和 <a href="" /> 匹配,但是与 <a name="" /> 不匹配,后者在 HTML 用于建立锚链接元素。文本变化是因为作者用锚设置标记包围了该区域:

 
CSS:
a:hover {color:green;}

HTML:
<a href="foo.com">This should turn green when you hover over it.</a>

<a name="anchor-name">
This should change color when hovered over, but doesn't
in Internet Explorer.
</a>

Mozilla 正确地遵循了 CSS 规范,该例中文本的颜色变成绿色。有两种方法可以让 Mozilla 的行为和 Internet Explorer 一样,即悬停的时候不改变文本颜色:

  • 首先将 CSS 规则改为 a:link:hover {color:green;},这样只有链接(带有 href 属性)才会改变颜色。
  • 或者修改标记在文本开始之前加入 <a />,修改后锚仍然能正常工作。




回页首


特殊模式与标准模式

老 的浏览器如 Internet Explorer 4 在特定情况下会以所谓的特殊模式呈现。虽然 Mozilla 的目标是成为符合标准的浏览器,但是提供了三种模式支持带有这些特异行为的较老的网页。页面的内容和交付决定了 Mozilla 使用哪种模式。Mozilla 在 View -> Page Info(或 Ctrl-i)中列出呈现模式。页面选择哪种模式取决于文档类型。

文档类型(doctypes,即文档类型声明的缩写)如下所示:

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

蓝色部分称为公共标识符,绿色的部分称为系统标识符,是一个 URI。

标准模式

标准模式是最严格的呈现模式,根据 W3C HTML 和 CSS 规范呈现页面,不支持任何特异情况。如果满足下列条件,Mozilla 使用该模式:

  • 如果页面以 text/xml mimetype 或者其他 XML 或 XHTML mimetype 发送
  • IBM 文档类型之外的任何“DOCTYPE HTML SYSTEM”文档类型(比如 <!DOCTYPE HTML SYSTEM "http://www.w3.org/TR/REC-html40/strict.dtd">
  • 没 DTD 的文档类型或未知的文档类型

准标准模式

Mozilla 引入准标准模式有一个原因:CSS 2 中的一部分破坏了基于小图片在表格中精确布局的设计。不是为用户组成一幅完整的图片,而是在每个小图片后面都带一段间隙。图 5 所示的旧的 IBM 主页给出了一个例子。


图 5. 图片间隙
图片间隙

除了图片间隙问题外,准标准模式基本上和标准模式完全相同。这个问题常常出现在符合标准的页面上,并造成不正确的显示。

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">
  • IBM 文档类型(<!DOCTYPE html SYSTEM "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd">

请阅读相关资料进一步了解 图片间隙问题

特殊模式

目 前 Web 上到处充斥着不合法的 HTML 标记以及依靠浏览器的缺陷工作的标记。早在老的 Netscape 浏览器当还是市场领先者的时候就有这方面缺陷。Internet Explorer 出现时,为适应当时的内容而模仿了这些缺陷。随着新的浏览器进入市场,原来的这些缺陷,通常称为特异情况(quirks),为保持向后兼容大部分保留了下来。Mozilla 在特殊呈现模式中支持很多这样的特异情况。要注意,由于这些特异情况,页面与完全符合标准的情形相比呈现速度更慢。多数网页都用这种模式呈现。

Mozilla 在下面情况下使用特殊模式:

  • 没有指定文档类型
  • 文档类型没有系统标识符(比如 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

如果希望进一步了解相关内容,请阅读 List of QuirksList of Doctypes and What Modes They Cause





回页首


事件差异

在事件方面,Mozilla 和 Internet Explorer 几乎完全不同。Mozilla 事件模型按照 W3C 和 Netscape 模型。在 Internet Explorer 中,如果从事件中调用一个函数,可以通过 window.event 访问 event 对象。Mozilla 把 event 对象传递给事件处理程序。必须通过参数把该对象明确传递给调用的函数。下面是一个跨浏览器事件处理的例子:

 
<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>

事件对象公开的属性和函数的名称在 Mozilla 和 Internet Explorer 中也常常不同,如表 4 所示。

表 4. Mozilla 和 Internet Explorer 中的事件属性

Internet Explorer 名称 Mozilla 名称 说明
altKey altKey 布尔属性,表示事件过程中是否按下了 alt 键。
cancelBubble stopPropagation() 用于停止事件进一步沿树上行。
clientX clientX 事件的 X 坐标,相对于客户机。
clientY clientY 事件的 Y 坐标,相对于客户机。
ctrlKey ctrlKey 布尔属性,表明事件过程中是否按下了 Ctrl 键。
fromElement relatedTarget 对于鼠标事件来说,指的是鼠标从上移走的那个元素。
keyCode keyCode 用于键盘事件,表示所按下的键的数字。对于鼠标事件,其值为 0。
returnValue preventDefault() 用于防止执行事件的默认动作。
screenX screenX 事件的 X 坐标,相对于屏幕。
screenX screenY 事件的 Y 坐标,相对于屏幕。
shiftKey shiftKey 布尔属性,表明事件过程中是否按下了 Shift 键。
srcElement target 事件最初指派到的元素。
toElement currentTarget 用于鼠标事件,鼠标移动到的当前元素。
type type 返回事件名。

附加事件处理程序

Mozilla 提供了两种方法通过 JavaScript 附加事件。第一种是所有浏览器都具备的,即直接在对象上设置 event 属性。要设置 click 事件处理程序,可以向该对象的 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 完全支持向 DOM 节点附加监听器的 W3C 标准方式。使用 addEventListener()removeEventListener() 方法的好处是能够对同一个事件类型添加多个监听器。两种方法都需要三个参数:事件类型、函数引用以及监听器是否能够在捕获阶段捕获事件的布尔值。如果这个 布尔参数设为 false,则只捕获上行的事件。W3C 事件有三个阶段:捕获、到达目标和上行。每个事件对象都有一个 eventPhase 属性用数字表示所处的阶段(从 0 开始)。每当触发一个事件时,事件都从 DOM 的最外层元素即 DOM 树最顶端的元素开始。然后沿着到目标最近的路径在 DOM 中下行,称为捕获阶段。事件到达目标的时候称为目标抵达阶段。到达目标后,事件再沿着 DOM 树回到最外层的节点,称为上行(冒泡)。Internet Explorer 的事件模型只有上行阶段,因此,只要将第三个参数设置为 false 就能模仿 Internet Explorer 的行为:

 
<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>

与设置属性相比,addEventListener()removeEventListener() 的优点是可以为同一个事件设置多个监听器,调用不同的函数。因此,删除事件监听器要求传递的三个参数和添加时设定的三个参数完全相同。

Mozilla 不支持 Internet Explorer 将“script”标签转变成事件处理程序的方法,后者为“script”增加了 forevent 属性(如表 5 所示)。也不支持 attachEventdetachEvent 方法。相反,应该使用 addEventListenerremoveEventListener 方法。Internet Explorer 不支持 W3C 事件规范。

表 5. Mozilla 与 Internet Explorer 的事件方法差异

Internet Explorer 方法 Mozilla 方法 说明
attachEvent(aEventType, aFunctionReference) addEventListener(aEventType, aFunctionReference, aUseCapture) 向 DOM 元素添加事件监听器。
detachEvent(aEventType, aFunctionReference) removeEventListener(aEventType, aFunctionReference, aUseCapture) 从 DOM 元素删除事件监听器。




回页首


富文本编辑

虽然 Mozilla 自诩为最符合 W3C 标准的浏览器,但是如果不存在相关的 W3C 标准,它也可以支持非标准的功能,如 innerHTML 和富文本编辑。

Mozilla 1.3 实现了 Internet Explorer 的 designMode 特性,将 HTML 文档变成了一个富文本编辑器字段。变成了编辑器之后,就可以通过 execCommand 在文档上执行命令。Mozilla 不支持 Internet Explorer 的 contentEditable 属性,后者允许编辑任何组件。可以使用 iframe 增加富文本编辑器。

富文本差异

Mozilla 支持通过 IFrameElm.contentDocument 访问 iframe 文档对象的 W3C 标准,而 Internet Explorer 要求通过 document.frames["name"] 访问它,然后再访问最终得到的 document

 
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;
}

Mozilla 和 Internet Explorer 的另一个区别是富文本编辑器所创建的 HTML。Mozilla 默认对生成的标记使用 CSS。但是,Mozilla 允许使用 useCSS execCommand 分别改为 true 和 false 来在 HTML 和 CSS 之间切换。Internet Explorer 总是使用 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>

下面列出了 Mozilla 支持的 execCommand 命令:

表 6. 富文本编辑命令

命令名 说明 参数
bold 决定所选内容是否以粗体显示。 ---
createlink 从选中的文本创建 HTML 链接。 链接的 URL
delete 删除所选内容。 ---
fontname 改变所选文本使用的字体。 使用的字体名(比如 Arial)
fontsize 改变所选文本的字体大小。 使用的字体大小
fontcolor 改变所选文本使用的字体颜色。 使用的颜色
indent 缩进光标所在的块。 ---
inserthorizontalrule 在鼠标位置插入 <hr> 元素。 ---
insertimage 在鼠标位置插入图片。 图片的 URL
insertorderedlist 在当前位置插入有序列表(<ol>)元素。 ---
insertunorderedlist 在光标位置插入无序列表(<ul>)元素。 ---
italic 切换所选内容的的斜体属性。 ---
justifycenter 当前行居中对齐。 ---
justifyleft 当前行左对齐。 ---
justifyright 当前行右对齐。 ---
outdent 减少光标所在块的缩进。 ---
redo 恢复撤销的上一个命令。 ---
removeformat 去掉所选内容的全部格式。 ---
selectall 选择富文本编辑器中的全部内容。 ---
strikethrough 切换所选文本的删除线。 ---
subscript 将当前选择的内容改为下标。 ---
superscript 当前所选内容转化为上标。 ---
underline 添加或删除所选文本的下划线。 ---
undo 撤销上一次执行的动作。 ---
unlink 删除所选内容的链接信息。
分享到:
评论

相关推荐

    如何补上Linux缺乏应用软件的不便之处

    Mozilla浏览器则提供了与Internet Explorer和Chrome相当的网页浏览体验。这些开源软件的存在,使得Linux用户可以在不依赖传统商业软件的情况下,满足大部分日常计算需求。 然而,对于某些特定的专业应用,如Adobe的...

    JavaScript权威指南第四版.pdf

    对于使用最新标准,遵守标准的Web浏览器如Internet Explorer、Netscape和Mozilla等的开发者来说,这本书同样具有极大的价值。作者可以通过这本书学习如何使用JavaScript构建动态网页。因此,《JavaScript权威指南》...

    Windows软件的Linux类似替换.pdf

    1. Internet Explorer 的替换:Firefox、Netscape、Mozilla、Opera、Galeon、Konqueror、Epiphany、Dillo 等。 2. 命令行浏览器:Links、Lynx、Xemacs + w3 等。 二、电子邮件客户端软件 1. Outlook Express 的...

    salesforce apex ajax

    最后,文档提供了一套全面的迁移指南,帮助从旧版beta AJAX Toolkit过渡到新版的开发者能够顺利进行转换,避免常见的迁移陷阱,确保应用程序的连续性和兼容性。 总之,Salesforce Apex AJAX是Salesforce开发者手中...

    编写知名软件所用的语言.docx

    从低级系统如操作系统到复杂的Web应用程序,每种语言都有其优势和适用场景。例如,C++因其性能和灵活性在操作系统、图形界面和游戏开发等领域广泛使用;Java则在企业级应用和Android开发中占据主导地位;而PHP则在...

    一个包装IE控件的firefox插件

    标题中的“一个包装IE控件的Firefox插件”指的是一个特殊的Firefox扩展,它的设计目的是让基于Internet Explorer(IE)控件的应用程序能在Mozilla Firefox浏览器上正常运行。在Web开发领域,由于IE和Firefox使用了...

    Quickr部署系列

    这些集成和兼容性的支持使得QuickrDomino能够更好地融入到现有的IT环境中,并与其他关键的企业应用和服务协同工作。 ##### 安装升级简便 - **多种安装接口**: - 图形界面 - 命令行 - 响应文件 - **支持单节点和...

    2021-2022计算机二级等级考试试题及答案No.4022.docx

    - **知识点**: 虽然题目表述为只能使用 Internet Explorer 和 Netscape Navigator 进行浏览,但这一表述是错误的。实际上,现代 Web 浏览器还包括 Google Chrome、Mozilla Firefox、Safari 等多种选择。 - **重要性*...

    Flash 插件

    "ax"通常表示ActiveX控件,这在Windows系统中用于Internet Explorer浏览器。"gtbd_chrd_dn_aih"可能是特定地区、语言或发行渠道的标识符。这个安装程序旨在帮助用户在兼容的浏览器上安装和运行Flash内容。 随着...

    Tivoli Netcool OMNIbus_Installation and Deployment Guide_7.3.pdf

    - Microsoft Internet Explorer (IE11) ##### 4. 用户界面要求 用户界面应支持多语言环境,以便不同地区的用户能够方便地使用。 ##### 5. 在线帮助要求 为了便于用户获取帮助信息,系统需支持在线帮助功能,并且...

    浏览器内核分类

    Trident内核,也称为MSHTML或者Internet Explorer内核,是微软公司为自家的Internet Explorer浏览器开发的核心渲染引擎。Trident内核的特点在于对早期Web标准的支持较好,但同时也存在一些兼容性问题。例如,它在...

    Transmute书签互导工具

    Transmute支持多种流行浏览器的书签导入和导出,包括但不限于Google Chrome、Mozilla Firefox、Microsoft Edge(包括Chromium版)、Apple Safari、Opera、Internet Explorer等。这使得用户在更换或同时使用多个...

    Ajax 学习资源 中外都有

    - **简介**:该文章提供了将基于 Internet Explorer 的应用程序迁移到 Mozilla 浏览器的方法。 12. **Mozilla XUL 参考** - **网址**:http://www.xulplanet.com/ - **简介**:XUL(XML User Interface ...

    selenium2.0_中文帮助文档

    Selenium Server 是一个 Java 应用程序,它作为 WebDriver 服务器运行,接收来自客户端的命令,并在适当的浏览器中执行这些命令。 **4.3 如何设置 Firefox profile 使用 RemoteWebDriver** ```java FirefoxProfile...

    Bookmarks Converter-开源

    "Bookmarks Converter" 是一个开源解决方案,旨在解决这个问题,它允许用户将Internet Explorer的“收藏夹”转换为Netscape/Mozilla书签的格式,同时也支持反向转换。 Internet Explorer(IE)是微软开发的浏览器,...

    让IE8启动IE7兼容模式的代码

    标题中的“让IE8启动IE7兼容模式的代码”指的是在网页开发中,为了确保在Internet Explorer 8(简称IE8)浏览器上正确显示那些针对IE7设计的页面,可以使用特定的HTML元标签(meta tag)来强制IE8模拟IE7的渲染引擎...

Global site tag (gtag.js) - Google Analytics