Web 的未来:XHTML 2.0
原文地址:[url=http://www.]http://www.[/url]Nicholas Chase (nicholas@), 总裁, Chase and Chase, Inc.
2003 年 1 月 01 日
多年以来,HTML 只是在不断变大,却从未变小,因为新版本必须维护向后兼容性。这一情况将得以改变。XHTML 2.0 的第一个工作草案于 2002 年 8 月 5 日发布,一大新闻就是取消了向后兼容性;该语言终于得以继续发展。那么,作为一名开发人员您将得到什么回报呢?健壮的表单和事件表现如何呢?它们是研究不需要大量 JavaScript 的框架以及甚至层次结构菜单的更佳方法。
本文概述了 XHTML 2.0 中的新增功能以及将来可能会如何使用它。读者应该熟悉 HTML 和/或 XHTML 1.0。熟悉级联样式表(Cascading Style Sheet (CSS))是有帮助的,但不是必需的。
告别向后兼容性,引入结构
当万维网联盟(World Wide Web Consortium (W3C))于 2002 年 8 月 5 日发布 XHTML 2.0 的第一个工作草案时,最让人吃惊的是:与其先前的版本不同,它不是向后兼容的。对于先前的发行版,如从 HTML 4.01 转到 XHTML 1.0 以及后来从 XHTML 1.0 到 XTHML 1.1,变化都是添加一些内容;可以读取 XHTML 1.0(过渡的)文档的浏览器也可以理解 HTML 4.01 文档。而 XHTML 2.0 不是那样的。
如果您在两年前宣布我们今天将研究不带 img 标记或 bold 标记的 HTML 版本,那么大多数 Web 开发人员都会用怀疑的眼光看着您。然而,现在就是这样。除了彻底替换表单和框架外,XHTML 2.0 还除去了 b 、 i 和 img 标记(以及 big 、 small 和 tt ),甚至不赞成使用 br ,以准备从将来的发行版中除去它。但这是为什么呢?
原因在于大多数标记都是 表示性的 。它们的唯一目的就是给予浏览器指令,规定有关其内容应该如何显示,但却完全未提供有关其内容是什么的信息。例如,请考虑下面两个句子:
Presentational elements are, <i>for the most part</i>, <b>gone</b>.
和
Presentational elements are, <em>for the most part</em>, <strong>gone</strong>.
在没有样式表的情况下,这两个句子在浏览器中看起来是一样的,但只有第二个句子提供了有关原因的信息。事实上,从一开始 em (强调)和 strong 标记就出现在 HTML 中了,但多年以来作者们基本上已经忽略了它们,而专注于表现形式,这是以牺牲内容为代价的。
但这并不意味着只要您想使某些内容变成粗体或斜体,就应该将它们硬塞进这两个标记中。相反,除去表示性元素的整个目的是设法完成 CSS 的发明者的初衷,即应该根据内容所表示的东西来标记内容,而样式表应该用于美化内容。例如, 清单 1使用类别(class)来指出内容类型。
清单 1. 使用类别指定内容类型
程序代码:
<html> <head><title>Employee Notice</title> <style type="text/css"> .duedate { color: red; font-weight: bold; } .holiday { color: green; font-style: italic } </style> </head> <body> <h1>Notice</h1> <p>Employees should take note of the following important dates:</p> <ul> <li class="duedate">8/28/2002 (Progress reports due)</li> <li class="holiday">9/1/2002 (Labor Day)</li> <li class="duedate">10/28/2002 (Final reports due)</li> </ul> </body> </html>
在该页面中,日期类型可以由内容本身来确认,浏览器可以使用类别信息来决定如何为其设计样式, 类别可以确定显示哪一类内容,样式表可以对它进行适当的格式化
用这种观点研究它:断开( br )标记的目的无外乎是为了显示,因为实际上它并无任何内容。XHTML 2.0 不赞成使用 br 标记,而提倡使用 line 标记。 line 标记指定一种特殊的内容:通常是以后跟换行和回车这种方式呈现的一行文本或其它内容。例如,文本:
程序代码:
<p> public class HelloWorld {<br /> public static void main (String[] args){<br /> System.out.println("Hello world!");<br /> }<br /> } </p>
变成
程序代码:
<p> <line>public class HelloWorld {</line> <line>public static void main (String[] args){ </line> <line>System.out.println("Hello world!"); </line> <line>}</line> <line>}</line> </p>
这样,文档就有了一个表示行的实际对象,同样,段( p )标记表示一段内容。
为什么所有这些都很重要呢?因为 Web 不仅正日益成为人与人之间通信的场所,而且还日益成为软件应用程序(如服务器和搜索引擎索引器)之间进行通信的场所。而且,每个人(或者说几乎每个人)都使用相同浏览器的时代已经一去不复返了。开发人员正不断为不同设备(如 PDA 和移动电话)重新设计内容。语音触发的(voice-activated)系统已经离我们不远了。内容的结构意义正变得几乎与内容本身一样重要。
因此,XHTML 2.0 添加了节(section)和标题(heading)。HTML 一直都包含编号的标题 ― h1 到 h6 ,直到 2002 年 8 月 5 日的工作草案,还未将其撤消,但这只是一个时间问题。而 XHTML 2.0 使用通用标题和节。例如,可以嵌套节,从而赋予标题含义。以前用编号标题呈现的文档( 清单 2):
清单 2. 文档中的编号标题
程序代码:
<html> <head><title>Adding sections</title></head> <body> <h1>The Web's future: XHTML 2.0</h1> <p>by Nicholas Chase</p> <h2>Good-bye backward compatibility, hello structure</h2> <p>Why backward compatibility is over.</p> <h3>Presentation versus Structure</h3> <p>Using style sheets rather than presentational elements.</p> <h3>Lines</h3> <p>Line breaks are deprecated.</p> <h2>Sections</h2> <p>Creating more reasonable sections.</p> <h2>Navigation lists and menus</h2> <p>Hierarchical menus.</p> <h2>Links, links, everywhere</h2> <p>Adding links.</p> </body> </html>
可以用通用标题和节替换( 清单 3):
清单 3. 通用标题和节
程序代码:
<html> <head><title>Adding sections</title></head> <body> <section> <h>The Web's future: XHTML 2.0</h> <p>by Nicholas Chase</p> <section> <h>Good-bye backward compatibility, hello structure</h> <p>Why backward compatibility is over.</p> <section> <h>Presentation vs. Structure</h> <p>Using style sheets rather than presentational elements.</p> </section> <section> <h>Lines</h> <p>Line breaks are deprecated.</p> </section> </section> <section> <h>Sections</h> <p>Creating more reasonable sections.</p> </section> <section> <h>Navigation lists and menus</h> <p>Hierarchical menus.</p> </section> <section> <h>Links, links, everywhere</h> <p>Adding links.</p> </section> </section> </body> </html>
这种结构有两个优点。首先,应用程序(如搜索引擎 crawler)能够更容易地了解内容的相对重要性,其次,节是自包含的。在 HTML 中,节以其标题开始,所以在标题的前面不会出现内容(如介绍性内容)。 section 元素取消了这种约束,因为其内部的任何内容都是节的一部分。
导航列表和菜单
增加了一个会让 Web 开发人员大大受益的结构,那就是导航列表。由 nl 标记指定的导航列表的工作原理与其“表亲”有序列表( ol )和无序列表( ul )非常相似,但有一点不一样:导航列表的项仅在列表激活时才出现。因此,导航列表与层次结构的弹出菜单十分相似,这种弹出菜单很受欢迎,因为它们提供了许多导航信息,而且不会占据太多的屏幕空间。例如,肥皂剧站点可能有以下菜单( 清单 4):
清单 4. 使用导航列表
程序代码:
<nl> <name>Character Options</name> <li href="stay.html">Stay</li> <nl> <name>Leave</name> <li href="newjob.html">Job transfer</li> <li href="divorce.html">Divorce</li> <li href="fataldisease.html">Fatal disease</li> </nl> <li href="backburner.html">Back Burner</li> </nl>
当用户激活名称( Character Options )时,出现列表项。关于当用户激活主列表时子列表(如 Leave 菜单)是否会出现,还是用户必须激活子列表项本身以使其出现,工作草案并未说清楚。最终作者可能通过样式或事件来控制这一行为。在任何情况下,当输入焦点从主元素移开时,列表项就会消失。
链接,链接无处不在
您可能已经注意到:即使打算将前一个示例作为菜单,但它没有锚( a )标记。而 href 属性已经被正确放在了 li 元素上。这不是导航列表的特性,而是 XHTML 2.0 的新特性。与超文本相关的属性(如 href 、 target 和 accesskey )现在是公共属性集合(Common Attribute Collection)的一部分,它包括核心属性( class 、 id 和 title )、国际化属性( xml:lang ,它替换了 XHTML 1.1 中的 lang )和事件属性,事件属性来自 XML Events 建议书,正如您将在下面看到的。
这意味只要将 href 属性添加到任何元素,就可以将它转换成链接,而不一定要用锚标记包围单个元素。
这是否表示经过四年的努力,XLink 已经被 XHTML 2.0 采用了吗?总而言之,没有。事实上,XLink 和 XHTML 2.0 中规定的链接之间的差异是那些正从事各自建议书的开发人员之间争论的根源,所以在这个最初的公开工作草案和最后的建议书之间可能会做些更改。同时,可以组合使用该功能、导航列表、 link 元素,以及资源描述框架(Resource Description Framework (RDF))来复制 XLink 的大多数功能。
XForms 是一个与 XML 相关的建议书,并确实已经成为 XHTML 2.0 的一部分。
XForms
XML 表单语言(XML Forms Language (XForms))是研究表单的一种全新方法 ― 它象 XHTML 的其余部分一样 ― 内容、结构和表现是完全独立的。XForms 页面指定一个模型,该模型拥有有关表单自身的信息,然后,可以在页面周围散布表单元素,而不是被局限于单个表单元素。这意味着,您甚至可以在页面的同一区域中合并不同表单的元素。可以通过实例文档填充表单,实例文档是从表单元素上的 XPath 表达式引用的。表单元素自身也代表了特殊类型的对象,而不是描述在页面上它们是如何显示的。当更新表单元素中的数据时,会更新实例文档。当用户提交表单时,实际发送的是实例文档。例如,采用下面的简单表单( 清单 5):
清单 5. 简单的 HTML 表单
程序代码:
<html xmlns="http://www. <title>Preference Form</title> </head> <body> <h1>Preferences Form</h1> <form action="myformprocessor.jsp"> <p> Username: <input type="text" name="userid" /> <br /> Password: <input type="password" name="pass"/> </p> <p> Area preference: <select name="seatingpreference"> <option value="1">One</option> <option value="2">Two</option> <option value="3">Three</option> </select> </p> <p> <input type="submit" /> </p> </form> </body> </html>
清单 6显示了 XForms 版本的表单:
清单 6. XForms 版本的表单
程序代码:
<html xmlns="http://www. xmlns:xforms="http://www. <title>Preference Form</title> <xforms:model> <xforms:submitInfo method="postxml"/> <xforms:instance xmlns=""> <preferences> <person userid=""> <password></password> </person> <seatingpreference></seatingpreference> </preferences> </xforms:instance> </xforms:model> </head> <body> <h1>Preferences Form</h1> <p> <xforms:input ref="preferences/person@userid"> <xforms:caption>Username: </xforms:caption> </xforms:input> <br /> <xforms:secret ref="preferences/person/password"> <xforms:caption>Password: </xforms:caption> </xforms:secret> </p> <p> <xforms:selectOne ref="preferences/seatingpreference" selectUI="listbox"> <xforms:caption>Area preference: </xforms:caption> <xforms:item> <xforms:value>1</xforms:value> <xforms:caption>One</xforms:caption> </xforms:item> <xforms:item> <xforms:value>2</xforms:value> <xforms:caption>Two</xforms:caption> </xforms:item> <xforms:item> <xforms:value>3</xforms:value> <xforms:caption>Three</xforms:caption> </xforms:item> </xforms:selectOne> </p> <p> <xforms:submit> <xforms:caption>Submit Report</xforms:caption> </xforms:submit> </p> </body> </html>
术语说明:XForms 建议书特别说明了不存在单个表单的 XForms。它是多个 XForms 页面,不再是单个 XForm 页面。
表单一般需要进行验证。换句话说,数据字段必须包含有效数据等。XForms 使用 XML 模式来约束所提交的数据。另外,可以通过添加 XML Events(它也包括在 XHTML 2.0 中)来进一步增强 XForms 页面的功能。
XML Events
您可能已经熟悉了通过添加如 onclick 和 onmouseover 之类的事件在 Web 页面上使用事件。不会再有了。这些熟悉的属性已经被集成到 XHTML 2.0 中的 XML Events 模块所替代。XML Events 提供了一种通用的方法来指定事件发生时应该采取的操作。它的优点是您不受限于如鼠标单击之类的预定义事件。相反,可以定义您自己的事件以及触发它们时会发生什么。
XML Events 包含下列组件。如鼠标单击之类的事件可以作为目标。例如,在 清单 7所示的页面中:
清单 7. 要单击的页面
程序代码:
<html> <head><title>Rides</title></head> <body> <ul id="ridelist"> <li href="monorail.html">Monorail</li> <li href="Matterhorn.html">Matterhorn</li> <li href="coaster.html">Roller coaster</li> </ul> </body> </html>
用户可能单击第二个 li 元素 Matterhorn。当这发生时,鼠标单击事件从文档根行进到目标( li )并再次返回。顺序是:
(root) -- html -- body -- ul -- li -- ul -- body -- html -- (root)
向下行进到目标称为捕捉(capture)阶段,而再次向上行进称为冒泡(bubbling)阶段(并不是所有的事件都会冒泡)。在行进期间的任何时候,事件都可以传递已经被注册为观察器的对象(这表示它正在观察特定的事件),如果它看到事件,则执行特定操作。侦听器创建观察器。例如,在下面的序列中:
<ev:listener observer="ridelist" event="mousedown" handler="#myscript"/>
侦听器使 ul 元素(或者更准确一点说,是整个列表)成为观察器,因而,当用户单击任何列表项目时,观察器( ridelist )执行 myscript (但仍必须确定调用任意脚本的机制)。
XFrames
广受指责的框架也在 XHTML 2.0 中被替换了。XFrames 的第一个工作草案于 2002 年 8 月 6 日初次登场,此前一天 XHTML 2.0 宣布它将使用 XFrames 并试图解决传统 HTML 框架出现的问题。大多数问题是有关难于创建书签和刷新页面,以及不支持框架的搜索引擎无法索引适当内容。
在 XFrames 文档中,所包含内容的 URI 成为整个文档 URI 的一部分。例如,下面 清单 8中的页面可能表示带三个框架的 HTML 页面:
清单 8. XFrames 页面
程序代码:
<html> <head><title>XFrames</title></head> <body> <row> <frame id="header" /> <column> <frame id="menu"/> <frame id="content"/> </column> </row> </body> </html>
请注意,没有指定每个框架的 URI,但每个框架都有其自己唯一的标识符。因此,这个文档的 URI 可能是:
site.xfm#frames(header=header.xhtml,menu=menu.xhtml,content=main.xhtml)
然后,理解 XFrames 的浏览器将每个框架的内容与适当的 URI 相关联。当用户单击链接并更改个别框架的内容时,页面的整个 URI 都会更改,所以它始终显示用户正在查看的实际内容,“收藏”和“后退”按钮提供了准确的内容。
图像作为对象
2002 年 8 月 5 日工作草案的最后一个主要的更改包括除去了 img 标记并用 object 标记替代它。 object 标记实际上在 HTML 4.01 中就已经出现,但开发人员主要将它用于嵌入多媒体和 Java applet。然而,它一直都能支持图像。使用 object 标记的主要优点在于,它被设计成向下级联。换句话说,如果浏览器不能显示一个特定对象,那么它将显示该对象的内容。例如,遇到下列代码片断的浏览器首先试图装入电影。如果装入电影失败,则装入图像。如果装入图像失败,那么它只显示文本。
程序代码:
<object data="rides.mpeg" type="application/mpeg"> <object data="rollercoaster.jpg" type="image/jpg"> Jack tries to expand his horizons on the racing coasters. </object> </object>
后续步骤
2002 年 8 月 5 日的 XHTML 2.0 工作草案中唯一可以确定的事就是不能确定任何事情。在现在的草案和被作为建议书采纳的过程中,几乎可以肯定它将在某些方面发生变化,但强调结构和语义的目标不可能变化。出于这个原因,最好研究您现在构建的页面,并开始养成适当使用结构和样式的习惯。使用标记来指定某些事物是什么,而不是如何显示它们,并使用 CSS 来完成其余工作。总的来说,更多地考虑文档的结构以及您想要它们干什么,而不必太多地考虑它们将如何显示。