一旦页面加载完成了,SPA 不会因为用户的操作而进行页面的重新加载或跳转。取而代之的是利用 ">JavaScript 动态的变换 HTML 的内容,从而实现 UI 与用户的交互。由于避免了页面的重新加载,SPA 可以提供较为流畅的用户体验。 Dojo 是一个开源的,功能强大的 JavaScript 库。本文将基于 Dojo,分别从应用生命周期管理和页面布局管理等角度,介绍一种单页 Web 应用的实现方式。
传统的 Web 应用通过加载整个 Web 页面来实现与用户的交互。当用户点击一个链接或提交一个表单时,浏览器将向服务器请求一个全新的页面。这涉及到获取新页面的数据、卸载旧的页面和绘制新的页面。按照这种方式进行用户交互势必影响到 Web 应用的性能。并且,由于网络延时的存在,页面与页面之间的切换很可能会不流畅,从而进一步影响用户体验。
SPA 能够缓解传统的 Web 应用存在的问题。有关 SPA 的详细介绍可以访问 参考资源 以获得更多的信息。SPA 规定在一个页面的生命周期中不会有页面的重新加载,所有的用户交互和页面内容变换将限制在同一个 Web 页面中。换言之,SPA 用 Web 页面的局部变更来代替整个页面的重新加载,从而提高了用户体验和整体性能。
目前 SPA 已经有了较为广泛的应用,如 Google Docs、Gmail 等都是单页 Web 应用。
但是,相比于传统的 Web 应用,SPA 也存在着以下问题。
SPA 中动态变化的内容可能不会被搜索引擎找到。如果你的 Web 页面的内容希望被搜索引擎找到,那就不应该选择 SPA。 需要特殊处理才能实现浏览器的“后退”和“前进”功能。 SPA 需要在一个 Web 页面周期中加载所有需要的 HTML、CSS 等资源。这样有可能造成初次加载时间较长。本文将在“在创建适用于单页 Web 应用的 UI 布局”中介绍缓解该问题的方法。
Dojo 框架:Dojo 是一个强大的前端框架,它提供了方便的 Ajax 方法、丰富的小部件、数据结构、辅助函数、效果和布局帮助。有关 Dojo 的详细介绍请参考 Dojo 技术专题。Dojo 是一个较为活跃的开源项目,截止到 2012 年 8 月,Dojo 的最新版本是 1.8.0。本文中的所有实现将基于 Dojo 1.6.0。
综上所述,本文将分别从 Application controller 和 UI layout 的角度,详细介绍一种利用 Dojo 实现 SPA 的方法。
加载 Dojo,搭建开发环境
加载 Dojo
选择从 Google CDN 上加载完整的 Dojo Toolkit。由于部分文件在本地,所以需要借助 dojoConfig 中的 baseUrl和 modulePaths来注册本地文件。在代码清单 1 中注册了一个本地模块“app”,这样在 Web 页面的地址下的 app 路径中的所有文件都可以被 Dojo 文件系统找到。
清单 1. 加载 Dojo Toolkit
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6.0/dojo/dojo.xd.js" data-dojo-config="parseOnLoad: true, baseUrl: './', modulePaths: { app: 'app' }"></script>
准备开发环境和调试工具
下载并安装 Firefox 浏览器,并安装 Firebug 插件。
创建一个 Application controller
Application controller 的作用
作为一个模块化的控件库,大部分的 Dojo 的模块都是相对独立存在的。基于 Dojo 构造一个 Web 应用时,需要一个框架将这些模块(数据、UI 布局等)组装起来。Application controller 所起的作用主要是连接各个模块。同时,对于 SPA,在其生命周期内只会进行页面的局部更新,Application controller 还要肩负着记录各个模块状态和各个模块数据交互的任务。在实际应用中,Application controller 就是一个 JavaScript 对象,所有与 SPA 相关的内容,如数据、UI 布局、行为控制等都存放在这个对象中。
创建 Application controller 的一种方式
由于 Application controller 是一个 JavaScript 对象,因此创建的方式有多种。清单 2 利用 Dojo 的 module 机制创建一个对象作为 Application controller,这样能更好的将 JavaScript 和 HTML 分离。本文将在函数 startup 中完成对 SPA 的 UI 布局的初始化,下一节将详细介绍,这里先打印信息到 Firebug 的 Console 面板上。
清单 2. 创建一个空的 Application controller
// 向 Dojo 的文件系统注册一个模块“app.Application” dojo.provide("app.Application"); dojo.declare("app.Application", [], { startup: function() { console.log("SPA starts up."); } });
由于在“加载 Dojo,搭建开发环境”中已经将 app 注册在 Dojo 的文件系统中。因此只要再调用 dojo.require 即可进行 Application controller 的实例化。清单 3 演示了如何利用 Application controller 初始化 SPA。
清单 3. 用 Application controller 初始化整个页面
<script> // 从 Dojo 的文件系统获取模块“app.Application” dojo.require("app.Application"); dojo.ready(function() { (new app.Application()).startup(); }); </script>
开发人员可以向 Application controller 添加方法来实现单页应用所需要的功能。如,可以添加 refresh 方法实现内容的更新。您可以在随本文提供的示例代码中看到 refresh 方法的声明及使用。