Web澳门太陽城集团登录网址 操作系统

基于 HTML5 创设 Web 操作系统

2012/09/29 · HTML5,
JavaScript · 1
评论 ·
HTML5,
Javascript

来源:IBM
Developerworks

简介: Web
操作系统有着古板操作系统比相当小概比拟的优势,如能够任何时间任何地方使用其余极端进行访问,数据保存在劳动器端,空间越来越大,数据安全性越来越好,能够使用服务器端的
CPU、内部存款和储蓄器等能源拓展进一步复杂的演算。不过当下的 Web 操作系统前端好多基于
Flex、Silverlight、ActiveX
插件等手艺开垦,存在着对运动器材的支撑性差,终端安全性差,开拓难度大等短处。

HTML5 是下一代 web
语言的正规化,具备包容性好,安全性高,功效丰盛,开荒方便人民群众等优点,非常适合如
Web 操作系统一类的富客户端互连网应用的前端开垦。本文将显得怎么着使用 HTML5
提供的有余新本事如:本地数据库、多线程开辟、录像帮衬、离线编制程序等构建二个着力的
Web 操作系统。

简介

古板的操作系统有着一些难以克制的后天不足,如仅能在本地终端访谈,或仅帮忙少数的远程访谈,限于本地终端的财富,总括技艺柔弱,存款和储蓄空间有限,贫乏有力的防火墙等一两种安全机制,安全性很糟糕。鉴于上述弱点,Web
操作系统应时而生 – Web
操作系统是一种基于浏览器的杜撰的操作系统,用户通过浏览器能够在内部实行应用程序的操作,以及相关数据的存放。Web
操作系统提供的主导服务有文本文档的开创与存款和储蓄,音频摄像文件的广播与存款和储蓄,提供对时间消息的支撑等,更加尖端的服务则带有即时通讯,邮件以致游戏等劳务。Web
操作系统战胜了守旧操作系统的后天不足,在互联网的协助下,它能够在其它时刻,任什么地点方经由任何协助Web
的终点举行访问,能够动用服务器端Infiniti的图谋及存款和储蓄能源,用户数据保存在劳动器端,安全性较高。

澳门太阳集团城网址 1

连带技艺

日前营造 Web 操作系统的前端本领首要有 Flex、Silverlight、ActiveX
插件等等,它们各有一部分优瑕疵。

Flex

Flex 是一个不错的富客户端应用框架,专注于页面显示,Adobe
专门的职业维护,统一稳固,何况其脚本语言 ActionScript3
是面向对象的,非常适合程序猿使用。短处则是功耗高,占用带宽多,对活动选用的支撑性差。

Silverlight

Silverlight 是由微软推出的用来跟 Flash 抗衡的
ENVISIONIA(富网络选拔)化解方案,优点是有着硬件级的加速功效,但它近来仍不成熟,对非
Windows 系统的支持性并相当不足好,且学习难度不小。

ActiveX 插件

ActiveX 插件同样是微软生产的 奥迪Q7IA
化解方案,它是三个怒放的减轻方案,能够包容二种语言,但是它的欠缺也是刚强的,用户须求调节浏览器的平安等第并下载插件本事运营哈弗IA 应用,相当的大地下跌了安全性。

HTML5

为促进 web 标准化运动的进步,W3C 推出了下一代 HTML 的正儿八经 –
HTML5,为众多的商店所支持,因而全部非凡的前景。它有以下特点:首先,为增高用户体验,强化了
web 网页的显现品质;其次,为适应 纳瓦拉IA 应用的前进,追加了本地数据库等 web
应用的效劳;再度,由于中度标准化以及广大浏览器厂家的极力辅助,它的包容性和安全性相当高;最终它是一种轻松的言语,轻巧为大范围开采者驾驭。更为珍惜的是,由于节省和耗电低,在运动道具上
HTML5 将有所更加大的优势。由此更合乎如 Web 操作系统一类的 福特ExplorerIA
应用的前端开辟。

系统简要介绍

本系统根据 HTML5 开采,利用 HTML5 引入的七种新技能如拖拽
API、摄像标签、本地数据库、draw
API、多线程开拓、离线编制程序等提供了多当中坚的 Web
操作系统情况,满含了对桌面包车型客车补助、应用程序的帮衬,提供了贰个简单易行的摄像播放器和记事本以及一个石英钟,并对系统日志进行了记录,其它还提供了对离线状态的支撑。

桌面完成

系统对桌面包车型大巴支撑至关心重视要不外乎应用程序图标的张开与拖拽,以及桌面包车型客车上下文菜单等。

桌面拖拽

桌面包车型地铁布局由自然数额的 div
组成,它们遵照程序依次排列在矩形的桌面上,为应用程序Logo的开荒与拖拽提供了主导的支撑。

清单 1. 创建 div

XHTML

var iconHolder = document.createElement(“div”); iconHolder.id =
‘iconHolder’ + i; iconHolder.className = “iconHolder”;
mainDiv.appendChild(iconHolder);

1
2
3
4
var iconHolder = document.createElement("div");
iconHolder.id = ‘iconHolder’ + i;
iconHolder.className = "iconHolder";
mainDiv.appendChild(iconHolder);

HTML5 提供了对 drag 事件的支撑,大大简化了达成拖拽的难度。通过对
dragstart 事件的监听,将被拖拽的应用程序Logo所在的 div
记录下来,作为拖拽的源。

清单 2. 拖拽扶助

XHTML

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); //
假诺拖拽至回收站,则删掉被拖拽Logo,否则调换两Logo地方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);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 中的应用程序Logo转移至目标 div 中。若指标 div
中已涵盖应用程序Logo,则将七个Logo的职位交换。若回收站Logo处于目的 div
中,回收站将发挥作用并将源 div 中的应用程序Logo删除。图 1
呈现了桌面拖拽的法力。

图 1. 桌面拖拽效果

澳门太阳集团城网址 2次第展开

先后能够以二种艺术张开,左键点击或通过上下文菜单打开。

透过监听 div 的 onclick 事件,获取要张开的应用程序 id,并选取 openApp
方法张开相应的应用程序可达成对左键点击的帮助。

清单 3. 左键点击

XHTML

iconHolder.onclick = function(ev){ if(ev.currentTarget.firstChild){
openApp(ev.currentTarget.firstChild.id); ev.stopPropagation(); } };

1
2
3
4
5
6
iconHolder.onclick =  function(ev){
if(ev.currentTarget.firstChild){
        openApp(ev.currentTarget.firstChild.id);
        ev.stopPropagation();
}
};

经过监听 div 的 oncontextmenu 事件,获取要开拓的应用程序 id,并利用
openAppContextMenu
方法呈现相应应用程序的上下文菜单,可完结对右键上下文菜单的接济。

清单 4. 上下文菜单

XHTML

iconHolder.oncontextmenu = function(ev){
if(ev.currentTarget.firstChild){
openAppContextMenu(ev.currentTarget.firstChild.id, ev);
ev.stopPropagation(); } return false; };

1
2
3
4
5
6
7
iconHolder.oncontextmenu =  function(ev){
if(ev.currentTarget.firstChild){
        openAppContextMenu(ev.currentTarget.firstChild.id, ev);
        ev.stopPropagation();
}
return false;
};

应用相应应用程序的
id,能够获得相应应用程序的脚本,并执行,同不时间在系统日志中著录下相应的操作。

清单 5. 先后展开

XHTML

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);// 实行应用程序 }

1
2
3
4
5
6
7
8
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. 开辟程序上下文菜单

澳门太阳集团城网址,XHTML

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;// 令上下文菜单反射率为 八分之四appContextMenu.innerHTML = “”; // 获取应用程序相应上下文菜单的源委 var
apps = getApps(); for(var i=0; i<apps.length; i++){
if(apps[i].appId == appId){ for(var j=0;
j<apps[i]澳门太陽城集团登录网址,.contextMenu.length; j++){ appContextMenu.innerHTML +=
“<div class=’appContextMenuItem’
onclick=\”appContextMenu.style.display=’none’;” +
apps[i].contextMenu[j].action + “\”
onmouseover=’this.style.background=\”darkblue\”‘
onmouseout=’this.style.background=\”#eee\”‘>”
+apps[Web澳门太陽城集团登录网址 操作系统。i].contextMenu[j].name+”</div>”; } break; } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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].appId == appId){
                        for(var j=0; j<apps[i].contextMenu.length; j++){
                        appContextMenu.innerHTML += "<div class=’appContextMenuItem’
                        onclick=\"appContextMenu.style.display=’none’;" +
                        apps[i].contextMenu[j].action + "\"
                        onmouseover=’this.style.background=\"darkblue\"’
                        onmouseout=’this.style.background=\"#eee\"’>"
                        +apps[i].contextMenu[j].name+"</div>";
                        }
                        break;
                 }  
}
}

应用程序的上下文菜单由名叫 appContextMenu 的 div 完毕,将 oncontextmenu
事件中的 clientX 及 clientY 作为上下文菜单现身的职位,并将其光滑度设置为
0.5。利用相应应用程序的 id
获取上下文菜单对应的从头到尾的经过,并将其填写至上下文菜单。

图 2 显示了应用程序上下文菜单展开时的成效。

图 2. 应用程序上下文菜单

澳门太阳集团城网址 3上下文菜单

桌面上下文菜单的兑现方式与应用程序上下文菜单的兑现格局基本临近,图 3
和图 4 分别是桌面以及职责栏的上下文菜单。

图 3. 桌面上下文菜单

澳门太阳集团城网址 4

 图 4. 义务栏上下文菜单

澳门太阳集团城网址 5录制播放器

系统提供了八个差相当的少的摄像播放器,它帮忙从系统外界拖拽录像文件实行播报。

符合网络媒体的向上,HTML5 提供了录制标签 video
以便于进步对录像的协助,大大简化了 web
播放器开采的难度,开荒人士仅凭几行代码,就足以付出出叁个基本功用完善的摄像播放器。

Web澳门太陽城集团登录网址 操作系统。清单 7. 录制标签的创设

XHTML

var video = document.createElement(‘video’); video.id =’video’;
video.src =”; video.width = 370; video.height = 260; video.controls =
‘controls’; video.className = ‘video’; appHolder.appendChild(video);
addDragSupport(appHolder);

1
2
3
4
5
6
7
8
9
var video = document.createElement(‘video’);
video.id =’video’;
video.src =”;
video.width  = 370;
video.height = 260;
video.controls = ‘controls’;
video.className = ‘video’;
appHolder.appendChild(video);
addDragSupport(appHolder);

清单 7 中结构了三个 video 标签并将其增加到一个名称叫 appHolder 的 div
中。代码的末尾一行为其增加了拖拽的协理。

HTML5 不但帮忙浏览器内的拖拽,也支撑浏览器与地面系统里头的拖拽。清单 8
展现了为多个 div 增多拖拽协理的进程。

清单 8. 增添拖拽扶助

JavaScript

function addDragSupport(dropbox){ document.addEventListener(“dragenter”,
function(e){ }, false); document.addEventListener(“dragleave”,
function(e){ }, false); dropbox.addEventListener(“dragenter”,
function(e){ }, false); dropbox.addEventListener(“dragleave”,
function(e){ }, false); dropbox.addEventListener(“dragenter”,
function(e){ e.stopPropagation(); e.preventDefault(); }, false);
dropbox.addEventListener(“dragover”, function(e){ e.stopPropagation();
e.preventDefault(); }, false); dropbox.addEventListener(“drop”,
function(e){ handleFiles(e.dataTransfer.files, e.currentTarget, e);
e.stopPropagation(); e.preventDefault(); }, false); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function addDragSupport(dropbox){
document.addEventListener("dragenter", function(e){
}, false);
document.addEventListener("dragleave", function(e){
}, false);
dropbox.addEventListener("dragenter", function(e){
}, false);
dropbox.addEventListener("dragleave", function(e){
}, false);
dropbox.addEventListener("dragenter", function(e){
e.stopPropagation();
e.preventDefault();
}, false);
dropbox.addEventListener("dragover", function(e){
e.stopPropagation();
e.preventDefault();
}, false);
dropbox.addEventListener("drop", function(e){
handleFiles(e.dataTransfer.files, e.currentTarget, e);
e.stopPropagation();
e.preventDefault();              
}, false);  
}

中间,handleFiles 函数表明了怎么对拖拽的文件实行拍卖。

清单 9. 拖拽管理

Web澳门太陽城集团登录网址 操作系统。JavaScript

function handleFiles(files, dropbox, e) { if(files.length == 0){//
若文件不设有,则用相应文本代替 var dt = e.dataTransfer; var text =
dt.getData(“text/plain”); var p = document.createElement(“p”);
p.innerHTML += text; dropbox.appendChild(p); return; } for (var i = 0; i
< files.length; i++) { var file = files[i]; var fileProcessor =
dropbox.firstChild; fileProcessor.classList.add(“obj”);
fileProcessor.file = file; // 添Gavin件 var reader = new FileReader();
reader.onload = (// 读取文件内容 function(aFileProcessor) { return
function(e) { aFileProcessor.src = e.target.result; }; }
)(fileProcessor); reader.readAsDataU宝马X3L(file); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function handleFiles(files, dropbox, e) {
    if(files.length == 0){// 若文件不存在,则用相应文本代替
         var dt = e.dataTransfer;
         var text = dt.getData("text/plain");
         var p = document.createElement("p");
         p.innerHTML += text;
         dropbox.appendChild(p);
         return;
}
 
for (var i = 0; i < files.length; i++) {
         var file = files[i];
         var fileProcessor = dropbox.firstChild;
         fileProcessor.classList.add("obj");
         fileProcessor.file = file; // 添加文件
 
         var reader = new FileReader();
         reader.onload = (// 读取文件内容
         function(aFileProcessor) {
                 return function(e) {
                 aFileProcessor.src = e.target.result;
};
}
)(fileProcessor);
  reader.readAsDataURL(file);
}
}

handleFiles
函数首先推断文件是不是留存,若不设有,则以相应文字替代,若存在,则对

具有文件相继进行拍卖。向 fileprocessor( 这里是摄像标签 )
添Gavin书,然后利用 FileReader 读取文件内容至 fileprocessor 张开始拍片卖。

Web澳门太陽城集团登录网址 操作系统。图 5 呈现了拖拽一个视频文件 movie.ogg 到播放器的效率。

图 5. 录像播放

澳门太阳集团城网址 6

Web澳门太陽城集团登录网址 操作系统。地点存款和储蓄

Web
操作系统常常将一大二分之一额存款和储蓄于服务器端,那样做的补益可想而知,数据存款和储蓄空间更加大,安全性更加好。但是如此做也许有不足之处,由于网络的牢固如故较本地球磁性盘差,所以在脱离网络的情景下,Web
操作系统不能赢得相应的数目能源,因而 Web
操作系统需求一定的探问本地存款和储蓄空间的力量,当然本地存款和储蓄空间仅是作为服务器端存款和储蓄的二个补充,它的上空有限,访谈也遭到肯定的范围。

长期以来,HTML 以 Cookie
作为拜候本地空间的艺术,但是,这种办法具备许多欠缺和不足,如存款和储蓄的数目格式过于简单,经常仅为键值对;存款和储蓄的半空中山大学小有限。为此,HTML5
提供了本地数据库以加强地点存款和储蓄空间的会见工夫,它是一个简化版的数据库,能够援救模拟的
SQL 以及简单的事务管理等作用。

系统为支撑本地存款和储蓄,成立了三个名称为 MyData 的数据库。清单 10
展现了数据库创立的历程。

清单 10. 创建数据库

XHTML

var db; var openDatabase; if(openDatabase != undefined) db =
openDatabase(‘MyData’, ”, ‘My Database’, 102400);

1
2
3
4
var db;
var openDatabase;
if(openDatabase != undefined)
     db = openDatabase(‘MyData’, ”, ‘My Database’, 102400);

里头 MyData 为数据库的名号,省略的参数为数据库的本子,My Database
为体现的称号,最终的数字为数据库预估长度(以字节为单位)。

系统日志将系统在某有时间的展现操作记录下来,本地数据库为其提供仓库储存扶助。日志在数据库中蕴藏为表
History,包蕴 3 个字段,分别为时间,操作,及操作的详细音讯。清单 11
呈现了系统是怎么记录日志的。

清单 11. 日志记录

XHTML

var time = new Date().getTime(); var action = “open app”; var details =
“open: ” + appId; addHistory(time, action, details);//
向系统日志中增添一条记下 function addHistory(time, action, details){
if(openDatabase != undefined) db.transaction( function(tx) {
tx.executeSql(‘CREATE TABLE IF NOT EXISTS History(time INTEGER, action
TEXT, details TEXT)’,[]);// 创设日志记录表 tx.executeSql(‘INSERT INTO
History VALUES(?, ?, ?)’, [time, action, details], // 插入一条日志
function(tx, rs) { //alert(“store: “+time+”-“+action+”-“+details); },
function(tx, error) { //alert(error.source + “::” + error.message); });
}); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var time = new Date().getTime();  
var action = "open app";
var details = "open: " + appId;
addHistory(time, action, details);// 向系统日志中添加一条记录
 
function addHistory(time, action, details){
if(openDatabase != undefined)
db.transaction(
function(tx) {
tx.executeSql(‘CREATE TABLE IF NOT EXISTS History(time INTEGER,
action TEXT, details TEXT)’,[]);// 创建日志记录表  
tx.executeSql(‘INSERT INTO History VALUES(?, ?, ?)’, [time,
action, details], // 插入一条日志
function(tx, rs) {  
//alert("store: "+time+"-"+action+"-"+details);  
              },  
function(tx, error) {
    //alert(error.source + "::" + error.message);  
});  
});  
}

清单的第3盘部显得了怎么样调用日志记录,第二片段显得了日志记录的详实经过。在一个transaction 中,首先决断表 History
是不是存在,若一纸空文,则开创它。第二有的进行一条 SQL
语句,向数据库中插入当前的日志。

透过搜寻表 History,我们得以查看系统日志,清单 12
呈现了什么从数据库中查询系统日志,并将其出示出来。

清单 12. 日记呈现

XHTML

var historyTable = document.getElementById(“historyTable”); // 定义表头
historyTable.innerHTML = “”; var th = document.createElement(‘thead’);
th.style = “color:#CC3300”; var th1 = document.createElement(‘td’);
th1.align = “center”; th1.width=300; th1.innerHTML = “Time”; var th2 =
document.createElement(‘td’); th2.align = “center”; th2.width=100;
th2.innerHTML = “Action”; var th3 = document.createElement(‘td’);
th3.align = “center”; th3.width=150; th3.innerHTML = “Details”;
th.appendChild(th1); th.appendChild(th2); th.appendChild(th3);
historyTable.appendChild(th); if(openDatabase != undefined)
db.transaction(function(tx) { tx.executeSql(‘SELECT * FROM History’,
[], function(tx, rs) { // 将日志逐个展现到表的各行中 for(var i = 0; i
< rs.rows.length && i<15; i++) { var tr =
document.createElement(‘tr’); var td1 = document.createElement(‘td’);
td1.style.paddingLeft = “3px”; td1.style.paddingRight = “3px”; var t =
new Date(); t.setTime(rs.rows.item(i).time); td1.innerHTML =
t.toLocaleDateString()+ ” “+t.toLocaleTimeString(); var td2 =
document.createElement(‘td’); td2.style.paddingLeft = “3px”;
td2.style.paddingRight = “3px”; td2.innerHTML = rs.rows.item(i).action;
var td3 = document.createElement(‘td’); td3.style.paddingLeft = “3px”;
td3.style.paddingRight = “3px”; td3.innerHTML = rs.rows.item(i).details;
tr.appendChild(td1); tr.appendChild(td2); tr.appendChild(td3);
historyTable.appendChild(tr); } }); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
var historyTable = document.getElementById("historyTable");
 
// 定义表头
historyTable.innerHTML = "";
var th = document.createElement(‘thead’);
th.style = "color:#CC3300";
var th1 = document.createElement(‘td’);
th1.align = "center";
th1.width=300;
th1.innerHTML = "Time";
var th2 = document.createElement(‘td’);
th2.align = "center";
th2.width=100;
th2.innerHTML = "Action";
var th3 = document.createElement(‘td’);
th3.align = "center";
th3.width=150;
th3.innerHTML = "Details";
th.appendChild(th1);  
th.appendChild(th2);  
th.appendChild(th3);
historyTable.appendChild(th);
 
if(openDatabase != undefined)
db.transaction(function(tx) {    
tx.executeSql(‘SELECT * FROM History’, [], function(tx, rs)
{  
      // 将日志逐条显示到表的各行中
for(var i = 0; i < rs.rows.length && i<15; i++) {                    
var tr = document.createElement(‘tr’);
var td1 = document.createElement(‘td’);
td1.style.paddingLeft = "3px";
td1.style.paddingRight = "3px";
 
var t = new Date();  
t.setTime(rs.rows.item(i).time);  
td1.innerHTML = t.toLocaleDateString()+
" "+t.toLocaleTimeString();
 
var td2 = document.createElement(‘td’);  
td2.style.paddingLeft = "3px";
td2.style.paddingRight = "3px";
td2.innerHTML = rs.rows.item(i).action;
 
var td3 = document.createElement(‘td’);
td3.style.paddingLeft = "3px";
td3.style.paddingRight = "3px";
td3.innerHTML = rs.rows.item(i).details;  
 
tr.appendChild(td1);  
tr.appendChild(td2);  
tr.appendChild(td3);
 
historyTable.appendChild(tr);                  
}  
});  
});

清单 12 中,首先得到用于显示的日记的 HTML 表格
historyTable,并安装其样式及表头。

接下来在一个 transaction( 事务 ) 中,实行一条 SQL
语句,查询系统日志,并将每条日志增多为 historyTable 中的一行以便显示。图
6 呈现了系统日志的功能。

图 6. 系统日志

澳门太阳集团城网址 7

记事本

系统提供了三个轻便易行的记事本,完结了文本文书档案的基本操作。文本文书档案包罗标题和内容几个显式属性,以及多个名叫id
的隐式属性。与系统日志类似,本地数据库为文本数据的囤积提供了尾部的支撑。图
7 显示了记事本程序的分界面。

图 7. 记事本

澳门太阳集团城网址 8

当编辑完文书档案的标题与内容后,点击左上角的保留按键,将施行 createFile
函数。清单 13 显示了 createFile 函数的详细进程。

Web澳门太陽城集团登录网址 操作系统。清单 13. 创办文件

XHTML

function createFile(fileId, fileTitle, fileContent){ var idx = 1; var
update = false;//false 表示新建,true 表示修改 if(openDatabase !=
undefined) db.transaction(function(tx) { tx.executeSql(‘CREATE TABLE IF
NOT EXISTS TextFiles(idx INTEGER, title TEXT, content TEXT)’,[]);//
创制文本文档表 tx.executeSql(‘SELECT * FROM TextFiles’, [],
function(tx, rs){ for(var i = 0; i < rs.rows.length; i++) { //
若文书档案存在,则修改它 if(rs.rows.item(i).idx == fileId){
db.transaction(function(tx) { tx.executeSql(‘UPDATE TextFiles SET
title=?, content=? WHERE idx=’+fileId, [fileTitle, fileContent],
function(tx, rs) { alert(“update successfully”); }); }); return; } } //
若文书档案不设有,则新建三个文书档案 if(rs.rows.length>0) idx =
rs.rows.item(rs.rows.length-1).idx + 1; db.transaction(function(tx) {
tx.executeSql(‘INSERT INTO TextFiles VALUES(?, ?, ?)’, [idx, fileTitle,
fileContent], function(tx, rs){ alert(“save successfully:
“+idx+”-“+fileTitle+ “-“+fileContent); createFileIcon(idx); },
function(tx, error) { alert(error.source + “::” + error.message); });
}); }); }); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
function createFile(fileId, fileTitle, fileContent){
     var idx = 1;
     var update = false;//false 表示新建,true 表示修改
 
     if(openDatabase != undefined)
         db.transaction(function(tx) {
         tx.executeSql(‘CREATE TABLE IF NOT EXISTS TextFiles(idx INTEGER,
         title TEXT, content TEXT)’,[]);// 创建文本文档表
         tx.executeSql(‘SELECT * FROM TextFiles’, [], function(tx, rs){
             for(var i = 0; i < rs.rows.length; i++) {
                // 若文档存在,则修改它
                 if(rs.rows.item(i).idx == fileId){
                     db.transaction(function(tx) {    
                     tx.executeSql(‘UPDATE TextFiles
                     SET title=?, content=?
                     WHERE idx=’+fileId,
                     [fileTitle, fileContent],
                     function(tx, rs) {  
                             alert("update successfully");
                     });  
                 });
                 return;
             }        
}    
// 若文档不存在,则新建一个文档        
if(rs.rows.length>0)
idx = rs.rows.item(rs.rows.length-1).idx + 1;
db.transaction(function(tx) {                        
tx.executeSql(‘INSERT INTO TextFiles VALUES(?, ?, ?)’, [idx, fileTitle, fileContent],
               function(tx, rs){  
               alert("save successfully: "+idx+"-"+fileTitle+ "-"+fileContent);  
               createFileIcon(idx);  
},  
function(tx, error) {
                alert(error.source + "::" + error.message);  
                 });  
             });
         });
     });
}

清单 13 首先在三个 transaction 中,首先判别用于存款和储蓄文本文书档案的表
TextFiles 是还是不是留存,若不设有,则创制它。然后经过查询表 TextFiles
推断文本文书档案是还是不是存在,若存在,则当前操作为更新操作,程序将实施一条 SQL
语句,对当前文本文书档案实行更新。若不设有,则取当前最大文书档案 id 并加 1
看作新文书档案的 id,并奉行一条 SQL 语句,将文档音信,满含文档id,以及标题和内容插入到数据库中,并于插入操作结束后的回调方法中,利用
createFileIcon 方法在桌面上为新文书档案创立三个文书档案Logo。清单 14 展现了
createFileIcon 方法的现实性经过。

清单 14. 创制文书档案Logo

XHTML

function createFileIcon(fileId){ var iconHolder; for(var
i=1;i<=120;i++){// 查询第一个为空的岗位 iconHolder =
document.getElementById(‘iconHolder’ + if(!iconHolder.firstChild ){ var
text = document.createElement(‘img’); text.src = “images/text.gif”;
text.id = fileId; iconHolder.appendChild(text); text.onclick =
function(ev){ if(ev.currentTarget){ openApp(‘notebook’);//
展开记事本应用程序 var saveHolder =
document.getElementById(‘saveHolder’); saveHolder.onclick = function(){
var title = document.getElementById(‘title’); var content =
document.getElementById(‘content’); createFile(fileId, title.value,
content.value);// 创立文本文书档案 }; var openedFileId =
ev.currentTarget.id; if(openDatabase != undefined)
db.transaction(function(tx) {// 查询数据库,呈现文书档案内容
tx.executeSql(‘SELECT * FROM TextFiles’, [], function(tx, rs){
for(var i = 0; i < rs.rows.length; i++) { if((rs.rows.item(i).idx+””)
== (openedFileId+””)){ var title = document.getElementById(‘title’); var
content = document.getElementById(‘content’); title.value =
rs.rows.item(i).title; content.value = rs.rows.item(i).content;} } });
}); ev.stopPropagation(); } }; break; } }//for }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function createFileIcon(fileId){
     var iconHolder;
     for(var i=1;i<=120;i++){// 查询第一个为空的位置
         iconHolder = document.getElementById(‘iconHolder’ + if(!iconHolder.firstChild ){
             var text = document.createElement(‘img’);
             text.src = "images/text.gif";
             text.id = fileId;
             iconHolder.appendChild(text);
             text.onclick =  function(ev){  
                 if(ev.currentTarget){
                 openApp(‘notebook’);// 打开记事本应用程序
                 var saveHolder = document.getElementById(‘saveHolder’);
                 saveHolder.onclick  = function(){
                     var title = document.getElementById(‘title’);
                     var content = document.getElementById(‘content’);
                     createFile(fileId, title.value, content.value);// 创建文本文档
                 };
 
             var openedFileId = ev.currentTarget.id;
             if(openDatabase != undefined)
             db.transaction(function(tx) {// 查询数据库,显示文档内容
             tx.executeSql(‘SELECT * FROM TextFiles’, [], function(tx, rs){
                 for(var i = 0; i < rs.rows.length; i++) {  
                 if((rs.rows.item(i).idx+"") == (openedFileId+"")){
                     var title = document.getElementById(‘title’);
                     var content = document.getElementById(‘content’);          
                     title.value = rs.rows.item(i).title;                  
                     content.value = rs.rows.item(i).content;}    
                              }
                });
});
   ev.stopPropagation();
}
};
break;
}    
}//for
}

清单 14 首先在桌面中搜寻二个空的 div,然后创立多少个文书档案Logo,并将其填充至
div。文书档案Logo有贰个 id 属性对应文书档案id。末了为文书档案图标增添点击事件管理函数,当点击文书档案Logo时,会率先展开记事本,然后依照文书档案Logo的
id 查询数据库,提取文书档案的标题和内容张开始展览示。

图 8 展现了创办后的文本文书档案,点击后的效率如图 7 所示。

图 8. 文本文书档案

澳门太阳集团城网址 9时钟

系统提供了一个简便的石英钟用以呈现当前时光,它由二个表面以及分针和时针组成,能够随着岁月的变改换态地改动。今后的
web 应用使用 JavaScript 或 Flash 实现此类作用,其复杂总来说之。借助
HTML5 的 draw
API,能够轻巧地画出所需的图纸,非常的大的方便了此类应用的创设,其余,HTML5
还提供了过去 JavaScript 不可能支撑的二十四线程编制程序,大大进步了 web
应用的交互性和丰硕性。

石英钟有八个骨干的表面,它仅是一副轻松的图形,如图 9 所示。

图 9. 表盘

澳门太阳集团城网址 10

在表面之上,建有二个 canvas( 画布 ),如清单 15 所示。

清单 15. 画布

JavaScript

<canvas id=”canvas” width=”128px” height=”128px”></canvas>

1
<canvas id="canvas" width="128px" height="128px"></canvas>

接下去,清单 17
就要画布上模拟出石英钟以及分针,在那前边,额外部须求要三个后台线程用以总括时间,它被定义在名称叫time.js 的单身脚本文件中,如清单 16 所示。

清单 16. 后台线程

XHTML

onmessage = function(event) { //var i = 1; setInterval(function() {
//i++; postMessage(“”); }, 60000); };

1
2
3
4
5
6
7
8
onmessage = function(event)
{
//var i = 1;
    setInterval(function() {
    //i++;
    postMessage("");
    }, 60000);
};

每过 60 分钟,后台线程将会上前台线程发送贰个空音讯,以告知前台线程有 60
分钟已经长逝了。

清单 17. 前台线程的开始化

XHTML

var canvas = document.getElementById(“canvas”); if (canvas == null)
return false; var context = canvas.getContext(‘2d’);//
那是三个二维的图像 context.lineWidth = 2; context.translate(64, 64);//
定义原点 // 开端化分针 context.beginPath(); context.moveTo(0,0);//
从原点开始 var date = new Date(); var mhx =
37*Math.cos((date.getMinutes()-15)*Math.PI/30); var mhy =
37*Math.sin((date.getMinutes()-15)*Math.PI/30); context.lineTo(mhx,
mhy);// 至分针末端所在地方 context.closePath(); context.stroke(); //
起头化时针 context.beginPath(); context.moveTo(0,0);// 从原点初步 var
date = new Date(); var hour = date.getHours(); if(hour>=12) hour =
hour – 12; var minute = date.getMinutes(); var hhx =
27*Math.cos((hour-3)*Math.PI/6 + minute*Math.PI/360); var hhy =
27*Math.sin((hour-3)*Math.PI/6 + minute*Math.PI/360);
context.lineTo(hhx, hhy);// 至时针末端所在地方 context.closePath();
context.stroke();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var canvas = document.getElementById("canvas");
if (canvas == null)  
return false;  
var context = canvas.getContext(‘2d’);// 这是一个二维的图像
context.lineWidth = 2;
context.translate(64, 64);// 定义原点
 
// 初始化分针
context.beginPath();
context.moveTo(0,0);// 从原点开始
var date = new Date();
var mhx = 37*Math.cos((date.getMinutes()-15)*Math.PI/30);
var mhy = 37*Math.sin((date.getMinutes()-15)*Math.PI/30);
context.lineTo(mhx, mhy);// 至分针末端所在位置
context.closePath();
context.stroke();
 
// 初始化时针
context.beginPath();
context.moveTo(0,0);// 从原点开始
var date = new Date();
var hour = date.getHours();
if(hour>=12)
hour = hour – 12;
var minute = date.getMinutes();
var hhx = 27*Math.cos((hour-3)*Math.PI/6 + minute*Math.PI/360);
var hhy = 27*Math.sin((hour-3)*Math.PI/6 + minute*Math.PI/360);
context.lineTo(hhx, hhy);// 至时针末端所在位置
context.closePath();
context.stroke();

前台线程首先会拿走
canvas,并设置表盘宗旨为坐标原点。然后,获取当前时间,总结分针当前所应指向的坐标,然后从原点出发,画出分针。对于时针,若系统为
24 小时制,须求首先转化为 12 小时制,此后的拍卖接近于分针。

接下去,供给将前台与后台线程联系起来,利用 HTML5
提供的八线程编制程序方法,证明 Worker 对象作为后台线程的代理,并选拔onmessage 事件,对后台线程发出的新闻举办拍卖。

清单 18. 前台线程的 onmessage 事件

XHTML

var worker = new Worker(“js/timer.js”); worker.onmessage =
function(event){ context.clearRect(-64, -64, 128, 128);// 清空分针和时针
// 重画分针 context.beginPath(); context.moveTo(0,0);// 从原点早先 var
date = new Date(); var mhx =
37*Math.cos((date.getMinutes()-15)*Math.PI/30); var mhy =
37*Math.sin((date.getMinutes()-15)*Math.PI/30); context.lineTo(mhx,
mhy);// 至分针末端所在地方 context.closePath(); context.stroke(); //
重画时针 context.beginPath(); context.moveTo(0,0);// 从原点早先 var date
= new Date(); var hour = date.getHours(); if(hour>=12) hour = hour –
12; var minute = date.getMinutes(); var hhx =
27*Math.cos((hour-3)*Math.PI/6 + minute*Math.PI/360); var hhy =
27*Math.sin((hour-3)*Math.PI/6 + minute*Math.PI/360);
context.lineTo(hhx, hhy);// 至时针末端所在地点 context.closePath();
context.stroke(); }; worker.postMessage(“”);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var worker = new Worker("js/timer.js");
 
worker.onmessage = function(event){
 
    context.clearRect(-64, -64, 128, 128);// 清空分针和时针
 
    // 重画分针
    context.beginPath();
    context.moveTo(0,0);// 从原点开始  
    var date = new Date();
    var mhx = 37*Math.cos((date.getMinutes()-15)*Math.PI/30);
    var mhy = 37*Math.sin((date.getMinutes()-15)*Math.PI/30);
    context.lineTo(mhx, mhy);// 至分针末端所在位置
    context.closePath();
    context.stroke();
 
        // 重画时针
    context.beginPath();
    context.moveTo(0,0);// 从原点开始  
    var date = new Date();
    var hour = date.getHours();
    if(hour>=12)
    hour = hour – 12;
    var minute = date.getMinutes();
    var hhx = 27*Math.cos((hour-3)*Math.PI/6 + minute*Math.PI/360);
    var hhy = 27*Math.sin((hour-3)*Math.PI/6 + minute*Math.PI/360);
    context.lineTo(hhx, hhy);// 至时针末端所在位置
    context.closePath();
    context.stroke();
    };
    worker.postMessage("");

每过 60
分钟,后台线程将会上前台线程发送多少个空音讯,前台线程接收到消息后,首先,清空
canvas,然后再一次赢妥帖前几天子,总结分针以及时针对应的坐标,并再次画出时针和分针,进而成就对分针以及时针的创新,最后,每过
1 分钟,表盘更新贰回,从而模拟出动态时针的功力,如图 10 所示。

图 10. 时钟

澳门太阳集团城网址 11离线协理

虽说 Web
操作系统的帮助和益处是能够利用互联网随地随时进行访谈。然则在不可能访谈互连网的地方下,Web
操作系统便敬敏不谢发挥作用。由此 Web
操作系统有需求在离线状态下,仍可以对有的应用及其职能拓展支撑。事实上,各样浏览器已提供了不乏先例的缓存机制以提供对离线应用的支撑,然后那一个缓存机制往往是暂且的,不可控的。HTML5
为开辟职员提供了缓和此难点的另一种路子,它提供了一种长久性的,自定义的缓存方法,使得
Web 操作系统能够在离线的情景下,依旧援救部分使用的效果与利益。

HTML5
离线协助的主导是一个缓存清单,当中列出了亟需缓存的公文,本系统中的缓存文件
index.manifest,如清单 19 所示。

清单 19. 缓存清单

XHTML

CACHE MANIFEST #version 1.10 CACHE: index.html js/app.js js/clock.js
js/data.js js/database.js js/desktop.js js/history.js js/taskbar.js
js/timer.js js/file.js js/utils.js css/index.css images/appHolder1.png
images/background.jpg images/clock.png images/close.gif
images/computer.gif images/history.png images/network.gif
images/recycleBin.gif images/startIcon.png images/taskBar.png
images/vidioplayer.gif images/notebook.gif images/text.gif
images/save.gif movs/movie.ogg sounds/WindowsLogonSound.wav

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
CACHE MANIFEST
#version 1.10
CACHE:
index.html
js/app.js
js/clock.js
js/data.js
js/database.js
js/desktop.js
js/history.js
js/taskbar.js
js/timer.js
js/file.js
js/utils.js
css/index.css
images/appHolder1.png
images/background.jpg
images/clock.png
images/close.gif
images/computer.gif
images/history.png
images/network.gif
images/recycleBin.gif
images/startIcon.png
images/taskBar.png
images/vidioplayer.gif
images/notebook.gif
images/text.gif
images/save.gif
movs/movie.ogg
sounds/WindowsLogonSound.wav

其间,CACHE MANIFEST 标示本文件为缓存文件,#version 1.10
标示了本文件的本子。

CACHE
之后所列项支出的则是开垦职员自定义的剧情,在那之中累积了颇具在离线状态下用户访谈应用程序所必需的文本。

缓存清单定义甘休后,在 index.html
中插入这一个清单文件名,这样,当浏览器加载这些页面包车型地铁时候,会自动缓存清单文件中所罗列的文书。

清单 20. 使用缓存清单

XHTML

<html manifest=”index.manifest”>

1
<html manifest="index.manifest">

值得一说的是,若要帮忙离线缓存,除客户端浏览器的帮助以外,服务端的匡助也是至关重要的,就本系统所利用的
tomcat 来说,必要在其配置文件 web.xml 中增多清单 21 所示的条文。

清单 21. 劳务器端缓存配置

XHTML

<mime-mapping> <extension>manifest</extension>
<mime-type>text/cache-manifest</mime-type>
</mime-mapping>

1
2
3
4
<mime-mapping>
<extension>manifest</extension>
<mime-type>text/cache-manifest</mime-type>
</mime-mapping>

末尾,禁止使用本地机械的互联网,重新打开浏览器并访谈 Web
操作系统所在的网站,系统中的大多数应用程序仍旧得以健康办事,如图 11
所示。

图 11. 离线系统

澳门太阳集团城网址 12结束语

本文介绍了 Web
操作系统的基本知识,并与价值观的操作系统进行了比较,进而介绍了 HTML5
这种新技巧为 Web 操作系统开辟带来的益处,并与历史观的 web
前端开拓本事实行了比较,最终通过构建叁个宗旨的 Web 操作系统详细的显示了
Web 操作系统的基本形式和效能以及援救其运营的 web
前端开拓本事是何许贯彻其具体功效的。从本文的座谈中能够看看,基于 HTML5
的 Web 操作系统是前景的一大趋势,必将渐渐踏向大家的日常生活工作中去。

赞 2 收藏 1
评论

澳门太阳集团城网址 13

You may also like...

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图