基于HTML5构建Web操作系统
简介: Web 操作系统有着传统操作系统无法比拟的优势,如可以随时随地利用任何终端进行访问,数据保存在服务器端,空间更大,数据安全性更好,可以利用服务器端的 CPU、内存等资源进行更为复杂的运算。然而目前的 Web 操作系统前端大多基于 Flex、Silverlight、ActiveX 插件等技术开发,存在着对移动设备的支持性差,终端安全性差,开发难度大等缺点。
HTML5 是下一代 web 语言的标准,具有兼容性好,安全性高,功能丰富,开发便捷等优点,特别适合如 Web 操作系统一类的富客户端互联网应用的前端开发。本文将展示如何利用 HTML5 提供的多种新技术如:本地数据库、多线程开发、视频支持、离线编程等构建一个基本的 Web 操作系统。
简介
传统的操作系统有着一些难以克服的缺点,如仅能在本地终端访问,或仅支持有限的远程访问,限于本地终端的资源,计算能力薄弱,存储空间有限,缺乏强大的防火墙等一系列安全机制,安全性较差。鉴于以上缺点,Web 操作系统应运而生 – Web 操作系统是一种基于浏览器的虚拟的操作系统,用户通过浏览器可以在其中进行应用程序的操作,以及相关数据的存储。Web 操作系统提供的基本服务有文本文档的创建与存储,音频视频文件的播放与存储,提供对时间信息的支持等,更高级的服务则包含即时通信,邮件甚至游戏等服务。Web 操作系统克服了传统操作系统的缺点,在网络的支持下,它可以在任何时间,任何地点经由任何支持 Web 的终端进行访问,可以利用服务器端无限的计算及存储资源,用户数据保存在服务器端,安全性较高。
相关技术
目前构建 Web 操作系统的前端技术主要有 Flex、Silverlight、ActiveX 插件等等,它们各有一些优缺点。
Flex
Flex 是一个优秀的富客户端应用框架,专注于页面显示,Adobe 专业维护,统一稳定,而且其脚本语言 ActionScript3 是面向对象的,非常适合程序员使用。缺点则是耗能高,占用带宽多,对移动应用的支持性差。
Silverlight
Silverlight 是由微软推出的用以跟 Flash 抗衡的 RIA(富互联网应用)解决方案,优点是具备硬件级的加速功能,但它目前仍不成熟,对非 Windows 系统的支持性并不够好,且学习难度较大。
ActiveX 插件
ActiveX 插件同样是微软推出的 RIA 解决方案,它是一个开放的解决方案,可以兼容多种语言,不过它的缺点也是显而易见的,用户需要调整浏览器的安全等级并下载插件才能运行 RIA 应用,极大地降低了安全性。
HTML5
为推动 web 标准化运动的发展,W3C 推出了下一代 HTML 的标准 – HTML5,为众多的公司所支持,因此具有良好的前景。它有以下特点:首先,为增强用户体验,强化了 web 网页的表现性能;其次,为适应 RIA 应用的发展,追加了本地数据库等 web 应用的功能;再次,由于高度标准化以及诸多浏览器厂商的大力支持,它的兼容性和安全性非常高;最后它是一种简洁的语言,容易为广大开发者掌握。更为难得的是,由于节能和功耗低,在移动设备上 HTML5 将具有更大的优势。因此更适合如 Web 操作系统一类的 RIA 应用的前端开发。
系统简介
本系统基于 HTML5 开发,利用 HTML5 引入的多种新技术如拖拽 API、视频标签、本地数据库、draw API、多线程开发、离线编程等提供了一个基本的 Web 操作系统环境,包含了对桌面的支持、应用程序的支持,提供了一个简单的视频播放器和记事本以及一个时钟,并对系统日志进行了记录,此外还提供了对离线状态的支持。
桌面实现
系统对桌面的支持主要包括应用程序图标的打开与拖拽,以及桌面的上下文菜单等。
桌面拖拽
桌面的布局由一定数量的 div 组成,它们按照次序依次排列在矩形的桌面上,为应用程序图标的打开与拖拽提供了基本的支持。
清单 1. 创建 div
var iconHolder = document.createElement("div");
iconHolder.id = 'iconHolder' + i;
iconHolder.className = "iconHolder";
mainDiv.appendChild(iconHolder);
HTML5 提供了对 drag 事件的支持,大大简化了实现拖拽的难度。通过对 dragstart 事件的监听,将被拖拽的应用程序图标所在的 div 记录下来,作为拖拽的源。
清单 2. 拖拽支持
iconHolder.addEventListener("dragstart", function(ev) {
var dt = ev.dataTransfer;
dt.setData("text/plain", ev.currentTarget.id);// 记录被拖拽图标的 id
}, false);
iconHolder.addEventListener("drop", function(ev) {
var dt = ev.dataTransfer;
var srcIconHolderId = dt.getData("text/plain");
var srcIconHolder = document.getElementById(srcIconHolderId);
// 如果拖拽至回收站,则删掉被拖拽图标,否则互换两图标位置
if(ev.currentTarget.firstChild && ev.currentTarget.firstChild.id == "recycleBin" &&
srcIconHolder.firstChild.id != "recycleBin"){
srcIconHolder.innerHTML = "";
}else if(ev.currentTarget.firstChild){
var temp = ev.currentTarget.firstChild;
ev.currentTarget.appendChild(srcIconHolder.firstChild);
srcIconHolder.appendChild(temp);
}else{
ev.currentTarget.appendChild(srcIconHolder.firstChild);
}
}, false);
通过对 drop 事件的监听,可以获取拖拽的源,以及拖拽的目标 div。若目标 div 为空,则将源 div 中的应用程序图标转移至目的 div 中。若目标 div 中已包含应用程序图标,则将两个图标的位置互换。若回收站图标处于目标 div 中,回收站将发挥作用并将源 div 中的应用程序图标删除。图 1 显示了桌面拖拽的效果。
图 1. 桌面拖拽效果
程序打开
程序可以以两种方式打开,左键点击或通过上下文菜单打开。
通过监听 div 的 onclick 事件,获取要打开的应用程序 id,并利用 openApp 方法打开相应的应用程序可实现对左键点击的支持。
清单 3. 左键点击
iconHolder.onclick = function(ev){
if(ev.currentTarget.firstChild){
openApp(ev.currentTarget.firstChild.id);
ev.stopPropagation();
}
};
通过监听 div 的 oncontextmenu 事件,获取要打开的应用程序 id,并利用 openAppContextMenu 方法显示相应应用程序的上下文菜单,可实现对右键上下文菜单的支持。
清单 4. 上下文菜单
iconHolder.oncontextmenu = function(ev){
if(ev.currentTarget.firstChild){
openAppContextMenu(ev.currentTarget.firstChild.id, ev);
ev.stopPropagation();
}
return false;
};
利用相应应用程序的 id,可以获取对应应用程序的脚本,并执行,同时在系统日志中记录下相应的操作。
清单 5. 程序打开
function openApp(appId){
var time = new Date().getTime();
var action = "open app";
var details = "open: " + appId;
addHistory(time, action, details);// 记录系统日志
var appScript = getAppScript(appId);// 获取应用程序脚本
eval(appScript);// 执行应用程序
}
清单 6. 打开程序上下文菜单
function openAppContextMenu(appId, ev){
var appContextMenu = document.getElementById("appContextMenu");
appContextMenu.style.display="block";// 令上下文菜单可见
appContextMenu.style.pixelTop=ev.clientY;// 设置上下文菜单位置
appContextMenu.style.pixelLeft=ev.clientX;
appContextMenu.style.background = "#eee";
appContextMenu.style.color = "black";
appContextMenu.style.fontSize = "30";
appContextMenu.style.width = "200px";
appContextMenu.style.height = "220px";
appContextMenu.style.opacity = 0.5;// 令上下文菜单透明度为 50%
appContextMenu.innerHTML = "";
// 获取应用程序相应上下文菜单的内容
var apps = getApps();
for(var i=0; i<apps.length; i++){
if(apps[i]
补充:web前端 , HTML 5 ,