级别: 初级 Zhi Bo Zuo, 软件工程师, IBM Xin Rang Wang, 资深软件工程师, IBM Xue Wei Dong, 实习生, IBM Ming Zhao, 实习生, IBM
2009 年 9 月 14 日 Google Docs 如何让一个 Web 应用程序具有如此惊人的功能?他们利用了 Web 2.0 技术,该技术通过相对简单的代码提供了健壮的功能。在本文中,了解如何构建 Web 应用程序,以使用 Asynchronous JavaScript and XML (Ajax) 技术创建幻灯片演示。
简介
Web 2.0 技术正开始在企业防火墙之后展现其潜力,更多公司希望借助 Web 2.0 创造真实业务价值。我们第一次看到 Google Docs 时很是震惊。能够通过网络如此漂亮地实现如此复杂的应用,这十分惊人。在这篇由三部分组成的系列文章中,我们将向您展示如何使用 Ajax 技术构建像 Google Docs 这样的 Web 应用程序。有三种常用的办公文档:文本、电子表格和演示。本文集中研究演示格式。
在第 1 部分中,我们将着眼于用户界面 (UI) 的设计,这是在线应用程序最重要的方面之一。用户倾向于偏好他们熟悉的软件,所以在 Web 上制作又酷又常见的演示 GUI 可以很好地吸引用户采用我们的工具。在本文中,我们集中介绍出色界面的关键元素,并使之运行。
第 2 部分的重点是向我们的演示应用程序添加编辑特性。我们可修改字体风格,将图片拖放到演示中,以及修改文本内容。所有这些特性都将在第 2 部分中介绍。
最后,在第 3 部分中,我们将着眼于持久性。我们的原则是,Web 应用程序应当兼容现有应用程序。我们将在我们的系统中导出或导入其他演示文件,请紧记以下问题:
- 我们如何将一种文件类型转换为另一种类型?
- 我们如何保存当前工作以供用户稍后使用?
- 我们如何与他人共享演示?
让我们现在就开始开发用户界面。
开发 Web UI
我们的设计与图 1 所示画面相似(查看 大图)。LeftFrame 为 miniFrame,用于显示演示中的所有幻灯片,和 Power Point 或 OpenOffice.org 一样。中部窗口是 mainFrame,用户可在此处查看和编辑幻灯片内容。右方的框表示了 mainFrame 中选定元素的首选项。
图 1. 设计布局
DIV 对象和应用程序框架
在此项目中,我们将使用 DHTML 对象 DIV 来帮助格式化我们的视图。它不仅能够执行命令来便捷地修改文本风格,还具有缩放内容的特性。它是我们的演示中最重要的元素,几乎有 50% 的代码都是处理 DIV 对象的。
我们的框架中有 4 个主要 DIV 对象,如您在图 2(查看 大图)中所见。因为 ToolBar 和 LeftFrame 比较容易实现,所以我们在本文中将着重介绍 miniFrame 和 mainFrame 的实现。
图 2. 界面区域
miniFrame
MiniFrame 包含当前演示的所有幻灯片。此窗口有两个主要功能。首先它可以管理所有幻灯片,包括添加和删除幻灯片。其次,当用户修改 mainFrame 中的内容时,修改也会相应地显示在 miniFrame 中。人们期望其桌面应用程序具有此功能,所以我们想在 Web 上实现相同的功能。
管理幻灯片 —— miniFrame 的设计
既然 miniFrame 是一种容器,那么我们相信 DIV 对象是最好的选择,因为 DIV 对象能够包含任何其他 DHTML 元素。此外,每个幻灯片也要被一个 DIV 对象代表。图 3 显示了 miniFrame 中对象和 mainFrame 中对象之间的关系。我们将 miniFrame 中最大的幻灯片容器称为 Outside-DIV。该容器中将有许多不同的小 DIV 幻灯片,我们称之为 Inside-DIV。
图 3. Inside-DIV 和 Outside-DIV 容器
清单 1 显示了创建 miniFrame 的代码。
清单 1. miniFrame 的 DIV 定义
<DIV id=miniFrame SCROLLING=NO>
<div id='slide1' style="POSITION: absolute; SCROLLING="NO">\
</div>
<div id='slide2' style="POSITION: absolute; SCROLLING="NO">\
</div>
</DIV> |
管理幻灯片 —— 添加功能
显然,要管理幻灯片,您先需创建它们。所以,接下来我们将创建添加和删除幻灯片的功能。为此,我们需要操作 Outside-DIV 并重新分配其内容。对于 Add 操作,我们可以使用 DHTML 的 innerHTML 功能, 向 Outside-DIV 添加新的幻灯片代码。要保证现有幻灯片能保持其状态,每个幻灯片都要有自己独特的 ID 和顺序指示器。我们将建立一个称为 SlideIndex 的变量来指示不同的幻灯片。代码如下面的清单 2 所示。
清单 2. NewSlide()
function NewSlide(SlideIndex) {
window.document.getElementById("Minileft").innerHTML =
window.document.getElementById("Minileft").innerHTML +
"<div " + " style='position:absolute; top: "+(SlideIndex)*175+" px;'" +
"id='slide"+SlideIndex+
"</div>";
}
|
Delete 操作更复杂一些。我们不知道用户要删除哪个幻灯片,所以我们将使用变量 delSlideIndex 来解决。当我们删除幻灯片时,我们将重新编排每个幻灯片的位置。代码如清单 3 所示。
清单 3. DelSlide()
function DelSlide(delSlideIndex) {
var slides=window.document.getElementById("Minileft").all.tags('DIV');
slides[delSlideIndex].removeNode(true);
for(var no=delSlideIndex+1;no<slides .length;no+){
slides[no].style.top=parseInt(slides[no].style.top)- 175;
}
}
|
动态预览
在 PowerPoint 或其他演示应用程序中,当用户修改 mainFrame 中的内容时,相关的迷你幻灯片应当同时显示修改。这就是桌面版本的显示方式,所以我们希望匹配该功能,使用户感到舒适。您可以在下图 4 中看到这种效果的示例。
图 4. 使迷你幻灯片与编辑窗口同步
要实现此特性,我们必须检测 mainFrame 中的内容变更事件。在 DHTML 中,有两种可能事件您能用于检测变更:onkeyup() 和 onmouseup()。我们在 onPageLoad() 中初始化这两种事件捕获功能。您可在清单 4 中查看代码。
清单 4. onPageLoad()
function onPageLoad()
{
slideFrame.document.onmouseup = updataMainFrame;;
sildeWindow.document.onkeyup = updataMainFrame;
} |
updateMainFrame() 函数只将 mainFrame 的当前内容复制到相应的迷你幻灯片中。变量 CurrentSlide 指示焦点幻灯片。在清单 5 中查看此代码。
清单 5. updateMainFrame()
function updateMainFrame(CurrentSlide)
{
window.document.getElementById("slide"+CurrentSlide).innerHTML=
window.document.getElementById("MainFrame").innerHTML;
}
|
mainFrame
中部窗口为 mainFrame,用于显示演示中可编辑的内容。用户能够在此窗口中编辑图片和文本对象。我们使用另一个 DIV 元素来实现它,因为此对象可以容纳包括自身在内的所有其他对象。因为 DIV 对象有可编辑模式,当我们开启此模式时,DIV 中的所有对象都能被改变。在实现我们的在线演示时这将帮我们节省很多工作。图 5 突出显示了 mainFrame。
图 5. mainFrame
要创建一个能被编辑的 DIV,我们只用简单地将以下代码添加到 HTML 中:
<div id="mainFrame" contentEditable='true' SCROLLING=NO
style="overflow:hidden;" frameBorder="0" ></div> |
关键是将 contentEditable 属性设为真值。图 6 显示了当 mainFrame 中的一个 DIV 元素的 contentEditable 设为真值时,单击对象将在编辑模式中显示它。
图 6. 编辑模式中的 DIV 元素
幻灯片显示
您也许认为在 Web 站点上实现幻灯片显示会非常复杂。实际上,DHMTL 给您强大的工具来完成这项工作。在我们的项目中,我们将需要考虑每个幻灯片的效果,并以大尺寸显示它们以供观看。
要实现幻灯片显示效果,我们必须首先设置时间来控制我们的显示过程。使用 Javascript,您能够使用如清单 6 中的代码轻松做到这一点。
清单 6. 设置幻灯片显示效果
function SetTime()
{
TimeOutID = window.setInterval('doIt();',1000);
}
|
setInterval() 是关键函数。TimeOutID 是用于终止计时器的返回值。doIt() 是我们需要在每个间隔之后触发的过程。值 1000 将间隔设为 1000 毫秒。
接下来,我们创建完整窗口来显示每个幻灯片,并取相关内容置入其中。在清单 7 中,我们使用变量 EndIndex 来判断幻灯片是否到达最后一张。ShowIndex 记录了正在显示的幻灯片。要使视图全屏显示,我们只用将 mainFrame 设置为适当尺寸。所有这些都在 doIt() 函数中完成。
清单 7. 创建完整屏幕视图。
function doIt()
{
if(ShowIndex==EndIndex){
ShowIndex=0;
clearInterval(TimeOutID);
window.document.getElementById("MainFrame").style.zoom="100%";
return;
}
MainFrame.document.body.innerHTML=
window.document.getElementById("slide"+
ShowIndex).contentWindow.document.body.innerHTML;
if(ShowIndex==0)
{
window.document.getElementById("MainFrame").style.zoom="150%";
}
ShowIndex++;
} |
用户一般希望在 Slide Show 模式下进行查看的同时,手动控制幻灯片。这需要一个控制栏,它应当满足以下需求:
- 只在 Slide Show 模式中显示
- 指示每个幻灯片的索引
- 提供清晰的控制
我们的例子显示在图 7(查看 大图)中。
图 7. 幻灯片视图控制
清单 8 显示了创建此控制面板所必需的 HTML 代码。清单 9 显示了相关的 JavaScript 代码。
清单 8. Slide Show 控制面板的 HTML 代码
<div id=controlbar style="color: blue; position:absolute; width:1300;height:500;
left:7px; top:695px;z-index: 5; visibility:hidden;">
<table border="0" width="1045" cellspacing="0" bordercolor="#EEEEEE"
cellpadding="0"
bordercolor="#EEEEEE" bgcolor="#C0C0C0" height="34">
<tr>
<td width="100%" height="34">
<table border="0" width="550" cellspacing="0" bordercolor="#EEEEEE"
cellpadding="0" >
<tr>
<td width="97"> &
nbsp;
<input type="button" value="<<" name="B3"
onclick="myforword()">
</td>
<td width="150">
page:<input type="text" style="border:0px;" name="T1" size="5" value="0">
</td>
<td width="72">
<input type="button" value=">>" name="B1"
onclick="myback()">
</td>
<td width="45">
<input type="button" id="B2" size="10" value="Auto"
onclick="myauto()">
</td>
<td width="61">
<input type="button" id="B4" size="10" value="Cancel"
onclick="mycancel()">
</td>
</tr>
</table>
</td>
</tr>
</table>
</div> |
清单 9. Slide Show 控制面板的 JavaScript 代码
function myforword()
{
slideindex--;
doIt();
}
function myauto()
{
window.document.getElementById("B4").disabled=false;
window.document.getElementById("B2").disabled=true;
TimeOutID = window.setInterval('autodoit();', 1000);
}
function mycancel()
{
slideindex=-1;
doIt();
}
function myback()
{
slideindex++;
doIt();
}
function autodoit()
{
slideindex++;
doIt();
} |
结束语
使用 DHTML 和 DIV 对象以及 CSS,可相对容易地制作如同演示的 Web 应用程序。示例代码提供了一些如何使用 JavaScript DOM 来处理 CSS 的额外演示。我们将在第 2 部分中添加其他功能时详述此内容。
参考资料
作者简介  | 
|  | Zhi Bo Zuo 是来自中国北京 Lotus Notes/Domino Core 团队的软件工程师。他目前重点研究软件全球化和 Web 2.0 技术。 |
 | 
|  | Xin Rang Wang 是来自中国北京 Lotus Notes/Domino 团队的资深软件工程师。她目前重点研究基于 domino 的 Web 2.0 技术。 |
 | |  | Wei Dong Xue 是中国北京 Lotus Notes/Domino Core 团队的实习生。他对 Web 2.0 技术感兴趣。 |
 | |  | Ming Zhao 是中国北京 Lotus Notes/Domino Core 团队的实习生。他对 Web 2.0 技术感兴趣。 |
对本文的评价
|