xml地图|网站地图|网站标签 [设为首页] [加入收藏]

皇家88登陆手机版:JS仿iGoogle自定义首页模块拖拽

来源:http://www.ccidsi.com 作者:最新解决方案 人气:169 发布时间:2019-05-02
摘要:听大人说 HTML伍 营造 Web 操作系统 2012/09/29 · HTML5,JavaScript · 1评论 ·HTML5,Javascript 来源:IBMDeveloperworks 简介:  Web操作系统有着古板操作系统不能够比拟的优势,如能够任何时间任何地方

听大人说 HTML伍 营造 Web 操作系统

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

来源:IBM Developerworks

简介: Web 操作系统有着古板操作系统不能够比拟的优势,如能够任何时间任何地方使用此外极端进行走访,数据保存在劳务器端,空间越来越大,数据安全性更加好,可以行使服务器端的 CPU、内部存款和储蓄器等财富开始展览更进一步复杂的演算。然则当下的 Web 操作系统前端多数基于 Flex、Silverlight、ActiveX 插件等才具开垦,存在着对运动道具的支撑性差,终端安全性差,开辟难度大等毛病。

HTML5 是下一代 web 语言的行业内部,具有包容性好,安全性高,作用丰裕,开垦方便人民群众等优点,特别符合如 Web 操作系统1类的富客户端互连网应用的前端开垦。本文将显得怎样运用 HTML5提供的有余新才能如:本地数据库、三十二线程开采、摄像支持、离线编制程序等构建2个着力的 Web 操作系统。

简介

观念的操作系统有着一些难以制伏的后天不足,如仅能在本地终端访问,或仅帮助少数的中远距离访问,限于本地终端的能源,计算技能薄弱,存款和储蓄空间有限,贫乏有力的防火墙等一密密麻麻安全机制,安全性较差。鉴于上述缺点,Web 操作系统应时而生 – Web 操作系统是一种基于浏览器的杜撰的操作系统,用户通过浏览器能够在其间实行应用程序的操作,以及相关数据的囤积。Web 操作系统提供的主导服务有文本文书档案的创始与存款和储蓄,音频录像文件的播放与储存,提供对时间音讯的支撑等,越来越高端的服务则带有即时通讯,邮件以致游戏等劳务。Web 操作系统克制了思想操作系统的败笔,在网络的帮助下,它能够在其它时刻,任什么地点方经由任何支持Web 的终极实行访问,能够行使服务器端Infiniti的乘除及存款和储蓄能源,用户数量保存在服务器端,安全性较高。

皇家88登陆手机版 1

相关技能

近期营造 Web 操作系统的前端工夫主要有 Flex、Silverlight、ActiveX 插件等等,它们各有一些优缺点。

Flex

Flex 是3个上佳的富客户端应用框架,专注于页面突显,Adobe 专门的职业维护,统1牢固,而且其脚本语言 ActionScript三是面向对象的,分外适合工程师使用。缺点则是耗电高,占用带宽多,对运动接纳的支撑性差。

Silverlight

Silverlight 是由微软生产的用于跟 Flash 抗衡的 本田CR-VIA(富互连网选择)解决方案,优点是兼具硬件级的加速成效,但它近日仍不成熟,对非 Windows 系统的帮忙性并不够好,且学习难度相当的大。

ActiveX 插件

ActiveX 插件一样是微软推出的 汉兰达IA 消除方案,它是2个怒放的化解方案,能够相称多种语言,不过它的老毛病也是明摆着的,用户需求调动浏览器的安全等第并下载插件才干运作 MuranoIA 应用,比十分大地降落了安全性。

HTML5

为促进 web 规范化运动的开垦进取,W3C 推出了下一代 HTML 的正儿八经 – HTML五,为很多的商铺所支撑,由此具备杰出的前景。它有以下特征:首先,为增高用户体验,强化了 web 网页的呈现性能;其次,为适应 牧马人IA 应用的前进,追加了本地数据库等 web 应用的法力;再度,由于中度规范化以及众多浏览器厂家的卖力协理,它的包容性和安全性相当高;最终它是1种精简的言语,轻松为布满开荒者驾驭。更为谭何轻便的是,由于节俭和功耗低,在活动道具上 HTML5 将装有更加大的优势。因而更切合如 Web 操作系统一类的 MuranoIA 应用的前端开采。

系统简要介绍

本系统基于 HTML5 开采,利用 HTML伍 引入的有余新技艺如拖拽 API、摄像标签、本地数据库、draw API、二十八线程开垦、离线编制程序等提供了2个骨干的 Web 操作系统情形,包罗了对桌面包车型地铁支撑、应用程序的帮忙,提供了一个简短的摄像播放器和记事本以及二个时钟,并对系统日志举行了笔录,别的还提供了对离线状态的协理。

桌面落成

系统对桌面包车型客车帮忙入眼归纳应用程序Logo的开发与拖拽,以及桌面包车型大巴上下文菜单等。

桌面拖拽

桌面包车型客车布局由自然数额的 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 事件的监听,将被拖拽的应用程序图标所在的 div 记录下来,作为拖拽的源。

清单 贰. 拖拽支持

XHTML

iconHolder.add伊夫ntListener("dragstart", function(ev) { var dt = ev.dataTransfer; dt.setData("text/plain", ev.currentTarget.id);// 记录被拖拽Logo的 id }, false); iconHolder.add伊夫ntListener("drop", function(ev) { var dt = ev.dataTransfer; var srcIconHolderId = dt.getData("text/plain"); var srcIconHolder = document.getElementById(srcIconHolderId); // 尽管拖拽至回收站,则删掉被拖拽图标,不然调换两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 中的应用程序图标删除。图 1来得了桌面拖拽的功力。

图 一. 桌面拖拽效果

皇家88登陆手机版 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 方法展现相应应用程序的上下文菜单,可达成对右键上下文菜单的援救。

清单 四. 上下文菜单

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,能够获得相应应用程序的脚本,并实行,同时在系统日志中著录下相应的操作。

清单 五. 先后展开

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

清单 六. 开拓程序上下文菜单

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[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 彰显了应用程序上下文菜单展开时的法力。

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

皇家88登陆手机版 3上下文菜单

桌面上下文菜单的兑现格局与应用程序上下文菜单的贯彻情势基本类似,图 叁和图 肆 分别是桌面以及职务栏的上下文菜单。

图 三. 桌面上下文菜单

皇家88登陆手机版 4

 图 四. 职分栏上下文菜单

皇家88登陆手机版 5录像播放器

系统提供了1个简短的录像播放器,它辅助从系统外部拖拽录制文件进行播放。

符合互联网媒体的发展,HTML5 提供了录像标签 video 以便于进步对摄像的帮忙,大大简化了 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);

清单 柒 中结构了三个 video 标签并将其加多到二个名称叫 appHolder 的 div 中。代码的末梢一行为其增添了拖拽的帮助。

HTML5 不但协助浏览器内的拖拽,也援救浏览器与地面系统里面包车型客车拖拽。清单 8展现了为一个 div 加多拖拽支持的进度。

清单 捌. 增多拖拽协理

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 函数表明了如何对拖拽的文书举办拍卖。

清单 玖. 拖拽管理

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; // 增加文件 var reader = new FileReader(); reader.onload = (// 读取文件内容 function(aFileProcessor) { return function(e) { aFileProcessor.src = e.target.result; }; } )(fileProcessor); reader.readAsDataU奥迪Q5L(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( 这里是摄像标签 ) 增添文书,然后利用 FileReader 读取文件内容至 fileprocessor 展开始拍片卖。

图 5 显示了拖拽八个摄像文件 movie.ogg 到播放器的功效。

图 伍. 录像播放

皇家88登陆手机版 6

本土存储

Web 操作系统日常将超越一二分之一额存款和储蓄于服务器端,那样做的便宜总来说之,数据存储空间更加大,安全性更加好。不过如此做也有不足之处,由于互联网的安定团结依然较本地球磁性盘差,所以在退出网络的现象下,Web 操作系统无法得到相应的数码财富,因而 Web 操作系统必要自然的造访本地存款和储蓄空间的力量,当然本地存款和储蓄空间仅是作为服务器端存款和储蓄的1个填补,它的空中有限,访问也惨遭肯定的限量。

直白以来,HTML 以 Cookie 作为访问本地空间的秘诀,然则,这种方法具备广大弱点和不足,如存款和储蓄的数码格式过于简短,平日仅为键值对;存款和储蓄的长空尺寸有限。为此,HTML5提供了地面数据库以增加地点存储空间的访问才能,它是三个简化版的数据库,能够援助模拟的 SQL 以及轻便的事务管理等功用。

系统为永葆地点存款和储蓄,创造了3个名称为 MyData 的数据库。清单 ⑩显示了数据库创设的历程。

清单 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,蕴含 三 个字段,分别为时间,操作,及操作的详细音讯。清单 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);  
});  
});  
}

清单的率先部分显得了怎样调用日志记录,第三有个别显得了日记记录的详实进程。在四个transaction 中,首先决断表 History 是或不是留存,若不设有,则成立它。第二片段举办一条 SQL 语句,向数据库中插入当前的日记。

经过寻找表 History,我们得以查阅系统日志,清单 1二彰显了什么从数据库中询问系统日志,并将其出示出来。

清单 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<一伍; i ) { var tr = document.createElement('tr'); var td1 = document.createElement('td'); td一.style.paddingLeft = "三px"; td一.style.paddingRight = "三px"; var t = new Date(); t.setTime(rs.rows.item(i).time); td一.innerHTML = t.toLocaleDateString() " " t.toLocaleTimeString(); var td2 = document.createElement('td'); td二.style.paddingLeft = "三px"; td2.style.paddingRight = "三px"; td贰.innerHTML = rs.rows.item(i).action; var td三 = document.createElement('td'); td3.style.paddingLeft = "3px"; td3.style.paddingRight = "3px"; td三.innerHTML = rs.rows.item(i).details; tr.appendChild(td1); tr.appendChild(td二); tr.appendChild(td三); 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);                  
}  
});  
});

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

接下来在2个 transaction( 事务 ) 中,试行一条 SQL 语句,查询系统日志,并将每条日志增加为 historyTable 中的一行以便呈现。图 陆 展现了系统日志的功力。

图 陆. 系统日志

皇家88登陆手机版 7

记事本

系统提供了2个大约的记事本,达成了文本文书档案的基本操作。文本文档包罗标题和剧情七个显式属性,以及3个名称叫id 的隐式属性。与系统日志类似,本地数据库为文本数据的存储提供了底层的支撑。图 7 展现了记事本程序的分界面。

图 7. 记事本

皇家88登陆手机版 8

当编辑完文书档案的标题与内容后,点击左上角的保留开关,将施行 createFile 函数。清单 一三 呈现了 createFile 函数的详细经过。

清单 一3. 创制文件

XHTML

function createFile(fileId, fileTitle, fileContent){ var idx = 一; 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-壹).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);  
                 });  
             });
         });
     });
}

清单 壹三 首先在二个 transaction 中,首先判定用于存款和储蓄文本文书档案的表 TextFiles 是不是留存,若不设有,则创制它。然后通过查询表 TextFiles 推断文本文书档案是不是留存,若存在,则当前操作为更新操作,程序将推行一条 SQL 语句,对当前文本文书档案举行更新。若不设有,则取当前最大文书档案 id 并加 一看作新文书档案的 id,并推行一条 SQL 语句,将文书档案音信,包蕴文档id,以及标题和内容插入到数据库中,并于插入操作停止后的回调方法中,利用 createFileIcon 方法在桌面上为新文书档案创立一个文书档案Logo。清单 1四 显示了 createFileIcon 方法的求实经过。

清单 1四. 创制文书档案Logo

XHTML

function createFileIcon(fileId){ var iconHolder; for(var i=1;i<=120;i ){// 查询第3个为空的岗位 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
}

清单 1肆 首先在桌面中查究一个空的 div,然后创造3个文书档案Logo,并将其填充至 div。文书档案Logo有三个 id 属性对应文书档案id。最终为文书档案Logo增多点击事件管理函数,当点击文书档案Logo时,会率先张开记事本,然后遵照文书档案Logo的 id 查询数据库,提取文书档案的题目和剧情进行展示。

图 8 展现了创办后的文本文书档案,点击后的意义如图 七 所示。

图 8. 文本文书档案

皇家88登陆手机版 9时钟

系统提供了三个简短的时钟用以展现当前时光,它由1个表面以及分针和时针组成,能够随着时间的成形动态地改变。以后的 web 应用使用 JavaScript 或 Flash 实现此类功效,其复杂综上可得。借助 HTML伍 的 draw API,能够轻易地画出所需的图纸,十分的大的福利了此类应用的营造,其余,HTML5还提供了往年 JavaScript 不能够支撑的二十八线程编制程序,大大加强了 web 应用的交互性和丰裕性。

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

图 9. 表盘

皇家88登陆手机版 10

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

清单 15. 画布

JavaScript

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

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

接下去,清单 壹7就要画布上模拟出时钟以及分针,在那前边,额外部需要要1个后台线程用以总括时间,它被定义在名称为time.js 的独立脚本文件中,如清单 1陆 所示。

清单 1陆. 后台线程

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 分钟已经过去了。

清单 壹7. 前台线程的开头化

XHTML

var canvas = document.getElementById("canvas"); if (canvas == null) return false; var context = canvas.getContext('2d');// 那是1个2维的图像 context.lineWidth = 二; context.translate(6肆, 6四);// 定义原点 // 初叶化分针 context.beginPath(); context.moveTo(0,0);// 从原点早先 var date = new Date(); var mhx = 叁7*Math.cos((date.getMinutes()-15)*Math.PI/30); var mhy = 37*Math.sin((date.getMinutes()-15)*Math.PI/30); context.lineTo(mhx, mhy);// 至分针末端所在地点 context.close帕特h(); context.stroke(); // 发轫化时针 context.beginPath(); context.moveTo(0,0);// 从原点开始 var date = new Date(); var hour = date.getHours(); if(hour>=1二) hour = hour - 1贰; var minute = date.getMinutes(); var hhx = 贰七*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,并安装表盘大旨为坐标原点。然后,获取当前时刻,总结分针当前所应指向的坐标,然后从原点出发,画出分针。对于时针,若系统为 二四 小时制,须要首先转化为 1二 时辰制,此后的管理类似于分针。

接下去,必要将前台与后台线程联系起来,利用 HTML5提供的十六线程编制程序方法,注明 Worker 对象作为后台线程的代办,并使用 onmessage 事件,对后台线程发出的新闻进行管理。

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

XHTML

var worker = new Worker("js/timer.js"); worker.onmessage = function(event){ context.clearRect(-6四, -6四, 12八, 12捌);// 清空分针和时针 // 重画分针 context.beginPath(); context.moveTo(0,0);// 从原点初始 var date = new Date(); var mhx = 叁七*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.begin帕特h(); context.moveTo(0,0);// 从原点起首 var date = new Date(); var hour = date.getHours(); if(hour>=1二) hour = hour - 1二; 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 分钟,后台线程将会上前台线程发送3个空音讯,前台线程接收到音讯后,首先,清空 canvas,然后再次获得当前时光,总括分针以及时针对应的坐标,同等看待复画出时针和分针,从而做到对分针以及时针的更新,最后,每过 一 分钟,表盘更新壹次,从而模拟出动态时针的功效,如图 10 所示。

图 10. 时钟

皇家88登陆手机版 11离线支持

即使如此 Web 操作系统的帮助和益处是能够利用网络任何时间任何地方实行走访。但是在不可能访问互联网的处境下,Web 操作系统便无能为力发挥作用。由此 Web 操作系统有供给在离线状态下,还是可以对有的行使及其职能拓展协理。事实上,种种浏览器已提供了美妙绝伦的缓存机制以提供对离线应用的支撑,然后那么些缓存机制往往是一时半刻性的,不可控的。HTML5为开垦人士提供了消除此难题的另一种门路,它提供了一种恒久性的,自定义的缓存方法,使得 Web 操作系统能够在离线的情景下,还是接济部分接纳的成效。

HTML5离线援救的主导是贰个缓存清单,当中列出了特殊供给缓存的文书,本系统中的缓存文件 index.manifest,如清单 1玖 所示。

清单 1九. 缓存清单

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 一.10标示了本文件的版本。

CACHE 之后所列项支出的则是开采职员自定义的内容,当中积累了有着在离线状态下用户访问应用程序所供给的公文。

缓存清单定义停止后,在 index.html 中插入那么些清单文件名,那样,当浏览器加载那一个页面包车型的士时候,会活动缓存清单文件中所罗列的文本。

清单 20. 选拔缓存清单

XHTML

<html manifest="index.manifest">

1
<html manifest="index.manifest">

值得1提的是,若要帮衬离线缓存,除客户端浏览器的支撑以外,服务端的支撑也是不能缺少的,就本系统所使用的 tomcat 来说,供给在其布局文件 web.xml 中增多清单 2一 所示的条规。

清单 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 操作系统所在的网址,系统中的大多数应用程序照旧能够通常工作,如图 1一所示。

图 1一. 离线系统

皇家88登陆手机版 12结束语

正文介绍了 Web 操作系统的基本知识,并与古板的操作系统进行了比较,进而介绍了 HTML五那种新才具为 Web 操作系统开辟拉动的利润,并与理念的 web 前端开垦技能拓展了比较,最后经过营造一个主导的 Web 操作系统详细的变现了 Web 操作系统的基本形式和功效以及帮衬其运作的 web 前端开拓才能是何等兑现其实际职能的。从本文的商量中得以阅览,基于 HTML5的 Web 操作系统是现在的第一次全国代表大会趋势,必将慢慢走入人们的经常生活职业中去。

赞 2 收藏 1 评论

皇家88登陆手机版 13

简单介绍: Web 操作系统有着古板操作系统无法比拟的优势,如能够随地随时使用其余极端进行访问,数据保存在服务器端,空间更大,数据安全性越来越好,能够动用服务器端的 CPU、内部存款和储蓄器等能源实行更为复杂的演算。不过当下的 Web 操作系统前端多数基于 Flex、Silverlight、ActiveX 插件等技巧开垦,存在着对活动道具的援助性差,终端安全性差,开拓难度大等老毛病。
HTML五 是下一代 web 语言的正式,具备包容性好,安全性高,作用丰裕,开拓方便人民群众等优点,尤其契合如 Web 操作系统一类的富客户端网络应用的前端开采。本文将显得什么使用 HTML五提供的多样新手艺如:本地数据库、二10十二线程开采、录像匡助、离线编制程序等营造三个着力的 Web 操作系统。
简介
守旧的操作系统有着一些难以克制的老毛病,如仅能在本地终端访问,或仅帮助少数的远程访问,限于本地终端的财富,计算本领薄弱,存储空间有限,贫乏有力的防火墙等一类别安全机制,安全性较差。鉴于以上缺点,Web 操作系统应际而生 – Web 操作系统是1种基于浏览器的虚拟的操作系统,用户通过浏览器能够在个中开始展览应用程序的操作,以及有关数据的贮存。Web 操作系统提供的中央服务有文本文书档案的开创与仓库储存,音频摄像文件的播音与存款和储蓄,提供对时间消息的支撑等,更加高档的劳动则带有即时通讯,邮件以致游戏等服务。Web 操作系统克制了古板操作系统的缺点,在网络的帮助下,它能够在其它时刻,任何地方经由任何扶助Web 的极限进行访问,可以选取服务器端Infiniti的估摸及存储能源,用户数量保存在劳动器端,安全性较高。

本文实例讲述了JS仿i谷歌自定义首页模块拖拽特效的格局。分享给我们供大家参考。具体完毕情势如下:

连锁才干
当下营造 Web 操作系统的前端才具主要有 Flex、Silverlight、ActiveX 插件等等,它们各有局地优缺点。
Flex
Flex 是3个优秀的富客户端应用框架,专注于页面展现,Adobe 专门的学问维护,统一稳固,而且其脚本语言 ActionScript3是面向对象的,十三分适合技术员使用。缺点则是耗电高,占用带宽多,对活动选取的援助性差。
Silverlight
Silverlight 是由微软推出的用来跟 Flash 抗衡的 OdysseyIA(富网络使用)消除方案,优点是具备硬件级的加速功用,但它近来仍不成熟,对非 Windows 系统的援救性并不够好,且学习难度十分的大。
ActiveX 插件
ActiveX 插件同样是微软推出的 SportageIA 消除方案,它是一个盛开的缓和方案,能够相称三种语言,但是它的瑕疵也是众人周知的,用户须求调动浏览器的延安等第并下载插件技艺运作 陆风X八IA 应用,相当的大地下降了安全性。
HTML5
为拉动 web 标准化运动的进步,W3C 推出了下一代 HTML 的正规 – HTML5,为大多的店堂所支撑,因而具备天时地利的前景。它有以下特征:首先,为加强用户体验,强化了 web 网页的显现质量;其次,为适应 帕杰罗IA 应用的升华,追加了地点数据库等 web 应用的意义;再一次,由于中度规范化以及无数浏览器商家的不竭援助,它的包容性和安全性相当高;最终它是1种简单的语言,轻易为广大开辟者精晓。更为尊敬的是,由于节省和耗能低,在活动设备上 HTML伍 将具有越来越大的优势。因而更合乎如 Web 操作系统一类的 昂CoraIA 应用的前端开拓。
系统简要介绍
本系统依照 HTML5 开采,利用 HTML五 引入的各种新技术如拖拽 API、录制标签、本地数据库、draw API、二十多线程开垦、离线编制程序等提供了伍当中坚的 Web 操作系统景况,包罗了对桌面包车型大巴支撑、应用程序的援助,提供了3个简便的摄像播放器和记事本以及1个机械钟,并对系统日志实行了记录,别的还提供了对离线状态的匡助。
桌面完毕
系统对桌面包车型地铁支持入眼不外乎应用程序图标的开荒与拖拽,以及桌面包车型地铁上下文菜单等。
桌面拖拽
桌面包车型地铁布局由自然数额的 div 组成,它们依照程序依次排列在矩形的桌面上,为应用程序Logo的展开与拖拽提供了着力的支撑。
清单 1. 创建 div
 
var iconHolder = document.createElement("div");
 iconHolder.id = 'iconHolder' i;
 iconHolder.className = "iconHolder";
 mainDiv.appendChild(iconHolder);
HTML伍 提供了对 drag 事件的支持,大大简化了贯彻拖拽的难度。通过对 dragstart 事件的监听,将被拖拽的应用程序Logo所在的 div 记录下来,作为拖拽的源。
清单 二. 拖拽支持
 
iconHolder.addEventListener("dragstart", function(ev) {
 var dt = ev.dataTransfer;
 dt.setData("text/plain", ev.currentTarget.id);// 记录被拖拽Logo的 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);
通过对 drop 事件的监听,能够获得拖拽的源,以及拖拽的目的 div。若目标 div 为空,则将源 div 中的应用程序Logo转移至目标 div 中。若目标 div 中已包罗应用程序Logo,则将八个图标的地方交流。若回收站Logo处于目标 div 中,回收站将发挥效能并将源 div 中的应用程序Logo删除。图 一出示了桌面拖拽的机能。
图 1. 桌面拖拽效果皇家88登陆手机版 14
先后张开
程序能够以三种情势展开,左键点击或透过上下文菜单展开。
由此监听 div 的 onclick 事件,获取要开发的应用程序 id,并运用 openApp 方法打开相应的应用程序可完成对左键点击的支撑。
清单 三. 左键点击
 
iconHolder.onclick =  function(ev){
 if(ev.currentTarget.firstChild){
        openApp(ev.currentTarget.firstChild.id);
        ev.stopPropagation();
 }
 };
透过监听 div 的 oncontextmenu 事件,获取要打开的应用程序 id,并采纳openAppContextMenu 方法显示相应应用程序的上下文菜单,可落成对右键上下文菜单的支撑。
清单 四. 上下文菜单
 
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);// 推行应用程序
 }
清单 陆. 开垦程序上下文菜单
 
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.伍;// 令上下文菜单光滑度为 十分之五
 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 获取上下文菜单对应的内容,并将其填写至上下文菜单。
    图 二 显示了应用程序上下文菜单张开时的功用。
    图 二. 应用程序上下文菜单皇家88登陆手机版 15
    上下文菜单
    桌面上下文菜单的贯彻形式与应用程序上下文菜单的落实情势为主相仿,图 三和图 4 分别是桌面以及职分栏的上下文菜单。
    图 三. 桌面上下文菜单皇家88登陆手机版 16

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ";
<html xmlns="" >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>JS仿i谷歌自定义首页模块拖拽效果</title>
    <script type="text/javascript">
        var Common = {
            getEvent: function() {//ie/ff
                if (document.all) {
                    return window.event;
                }
                func = getEvent.caller;
                while (func != null) {
                    var arg0 = func.arguments[0];
                    if (arg0) {
                        if ((arg0.constructor == Event || arg0.constructor == MouseEvent) || (typeof (arg0) == "object" && arg0.preventDefault && arg0.stopPropagation)) {
                            return arg0;
                        }
                    }
                    func = func.caller;
                }
                return null;
            },
            getMousePos: function(ev) {
                if (!ev) {
                    ev = this.getEvent();
                }
                if (ev.pageX || ev.pageY) {
                    return {
                        x: ev.pageX,
                        y: ev.pageY
                    };
                }

 图 四. 职责栏上下文菜单皇家88登陆手机版 17
录像播放器
系统提供了二个简便的录制播放器,它扶助从系统外部拖拽摄像文件举办广播。
适合互连网媒体的前行,HTML五 提供了录像标签 video 以便于拉长对录像的支撑,大大简化了 web 播放器开垦的难度,开荒职员仅凭几行代码,就能够支付出三个基本成效完善的摄像播放器。
清单 7. 摄像标签的创办
 
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);
清单 七 中组织了一个 video 标签并将其增加到3个名字为 appHolder 的 div 中。代码的最后壹行为其增加了拖拽的支撑。
HTML五 不但支持浏览器内的拖拽,也补助浏览器与本土系统里面的拖拽。清单 八展现了为三个 div 增加拖拽援助的经过。
清单 八. 增添拖拽帮忙
 
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 函数表达了怎么对拖拽的文书实行管理。
清单 玖. 拖拽管理
 
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( 这里是录制标签 ) 增添文件,然后利用 File里德r 读取文件内容至 fileprocessor 开始展览处理。
图 五 展现了拖拽三个摄像文件 movie.ogg 到播放器的效果。
图 5. 录像播放皇家88登陆手机版 18

                if (document.documentElement && document.documentElement.scrollTop) {
                    return {
                        x: ev.clientX document.documentElement.scrollLeft - document.documentElement.clientLeft,
                        y: ev.clientY document.documentElement.scrollTop - document.documentElement.clientTop
                    };
                }
                else if (document.body) {
                    return {
                        x: ev.clientX document.body.scrollLeft - document.body.clientLeft,
                        y: ev.clientY document.body.scrollTop - document.body.clientTop
                    };
                }
            },
            getElementPos: function(el) {
                el = this.getItself(el);
                var _x = 0, _y = 0;
                do {
                    _x = el.offsetLeft;
                    _y = el.offsetTop;
                } while (el = el.offsetParent);
                return { x: _x, y: _y };
            },
            getItself: function(id) {
                return "string" == typeof id ? document.getElementById(id) : id;
            },
            getViewportSize: { w: (window.innerWidth) ? window.innerWidth : (document.documentElement && document.documentElement.clientWidth) ? document.documentElement.clientWidth : (document.body?document.body.offsetWidth:0), h: (window.innerHeight) ? window.innerHeight : (document.documentElement && document.documentElement.clientHeight) ? document.documentElement.clientHeight : (document.body ? document.body.offsetHeight : 0) },
            isIE: document.all ? true : false,
            setOuterHtml: function(obj, html) {
                var Objrange = document.createRange();
                obj.innerHTML = html;
                Objrange.selectNodeContents(obj);
                var frag = Objrange.extractContents();
                obj.parentNode.insertBefore(frag, obj);
                obj.parentNode.removeChild(obj);
            },
            firstChild: function(parentObj, tagName) {
                if (Common.isIE) {
                    return parentObj.firstChild;
                }
                else {
                    var arr = parentObj.getElementsByTagName(tagName);
                    return arr[0];
                }
            },
            lastChild: function(parentObj, tagName) {
                if (Common.isIE) {
                    return parentObj.lastChild;
                }
                else {
                    var arr = parentObj.getElementsByTagName(tagName);
                    return arr[arr.length - 1];
                }
            },
            setCookie: function(name, value) {
                document.cookie = name "=" value;
            },
            getCookie: function(name) {
                var strCookie = document.cookie;
                var arrCookie = strCookie.split("; ");
                for (var i = 0; i < arrCookie.length; i ) {
                    var arr = arrCookie[i].split("=");
                    if (!arr[1]) {
                        return "";
                    }
                    if (arr[0] == name) {
                        return arr[1];
                    }
                }
                return "";
            },
            delCookie: function(name) {
                var exp = new Date();
                exp.setTime(exp.getTime() - 1);
                var cval = this.getCookie(name);
                if (cval != null) document.cookie = name "=" cval ";expires=" exp.toGMTString();
            }
        }
        var Class = {
            create: function() {
                return function() { this.init.apply(this, arguments); }
            }
        }
        var Drag = Class.create();
        Drag.prototype = {
            init: function(titleBar, dragDiv, Options) {
                //设置点击是否透明,暗中同意透明五分之三
                titleBar = Common.getItself(titleBar);
                dragDiv = Common.getItself(dragDiv);
                this.dragArea = { maxLeft: -9999, maxRight: 9999, maxTop: -9999, maxBottom: 9999 };
                if (Options) {
                    this.opacity = Options.opacity ? (isNaN(parseInt(Options.opacity)) ? 100 : parseInt(Options.opacity)) : 100;
                    if (Options.area) {
                        if (Options.area.left && !isNaN(parseInt(Options.area.left))) { this.dragArea.maxLeft = Options.area.left };
                        if (Options.area.right && !isNaN(parseInt(Options.area.right))) { this.dragArea.maxRight = Options.area.right };
                        if (Options.area.top && !isNaN(parseInt(Options.area.top))) { this.dragArea.maxTop = Options.area.top };
                        if (Options.area.bottom && !isNaN(parseInt(Options.area.bottom))) { this.dragArea.maxBottom = Options.area.bottom };
                    }
                }
                else {
                    this.opacity = 60;
                }
                this.originDragDiv = null;
                this.tmpX = 0;
                this.tmpY = 0;
                this.moveable = false;
                this.dragArray = [];

地点存储
Web 操作系统平时将大多数多少存款和储蓄于劳动器端,那样做的补益可想而知,数据存款和储蓄空间更加大,安全性更好。但是那样做也有不足之处,由于互联网的休保护健康息依旧较本地磁盘差,所以在退出互联网的场景下,Web 操作系统无法获取相应的数码财富,因而 Web 操作系统须求自然的拜访本地存款和储蓄空间的技术,当然当地存款和储蓄空间仅是用作劳务器端存款和储蓄的三个补偿,它的长空有限,访问也遭到一定的界定。
直白以来,HTML 以 Cookie 作为访问本地空间的艺术,可是,那种措施有所广大缺点和不足,如存款和储蓄的数码格式过于简短,常常仅为键值对;存款和储蓄的空中尺寸有限。为此,HTML5提供了本土数据库以抓好地点存款和储蓄空间的拜会手艺,它是贰个简化版的数据库,能够帮助模拟的 SQL 以及轻便的事务管理等职能。
系统为永葆地点存款和储蓄,创设了二个名叫 MyData 的数据库。清单 十呈现了数据库制造的进程。
清单 十. 创办数据库
 
var db;
var openDatabase;
if(openDatabase != undefined)
    db = openDatabase('MyData', '', 'My Database', 102400);
里面 MyData 为数据库的称呼,省略的参数为数据库的版本,My Database 为体现的称谓,最终的数字为数据库预估长度(以字节为单位)。
系统日志将系统在某目前间的一颦一笑操作记录下来,本地数据库为其提供仓库储存扶助。日志在数据库中存款和储蓄为表 History,包涵 叁 个字段,分别为时间,操作,及操作的详细消息。清单 11显示了系统是怎么着记录日志的。
清单 1一. 日记记录
 
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局地显得了日志记录的详实进度。在3个transaction 中,首先剖断表 History 是或不是留存,若不存在,则开创它。第2有个别进行一条 SQL 语句,向数据库中插入当前的日志。
经过搜寻表 History,大家能够查阅系统日志,清单 1二呈现了怎么样从数据库中询问系统日志,并将其出示出来。
清单 12. 日记显示
 
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贰 中,首先获得用于突显的日记的 HTML 表格 historyTable,并设置其样式及表头。
下一场在一个 transaction( 事务 ) 中,实践一条 SQL 语句,查询系统日志,并将每条日志增多为 historyTable 中的壹行以便呈现。图 6 展现了系统日志的功能。
图 6. 系统日志皇家88登陆手机版 19

                var dragObj = this;
                var dragTbl = document.getElementById("dragTable");

记事本
系统提供了三个轻巧的记事本,完成了文本文书档案的基本操作。文本文书档案包罗标题和剧情多个显式属性,以及多少个名叫id 的隐式属性。与系统日志类似,本地数据库为文本数据的储存提供了底层的匡助。图 七 呈现了记事本程序的分界面。
图 7. 记事本皇家88登陆手机版 20

                titleBar.onmousedown = function(e) {
                    var ev = e || window.event || Common.getEvent();
                    //只同意通过鼠标左键举办拖拽,IE鼠标左键为1FireFox为0
                    if (Common.isIE && ev.button == 1 || !Common.isIE && ev.button == 0) {
                    }
                    else {
                        return false;
                    }

当编辑完文档的题目与内容后,点击左上角的保存按键,将实践 createFile 函数。清单 一3 呈现了 createFile 函数的详尽经过。
清单 一三. 成立文件
 
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;
             }        
 }   
 // 若文书档案不设有,则新建2个文书档案        
 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); 
                 }); 
             });
         });
     });
 }
清单 一三 首先在多个 transaction 中,首先判定用于存款和储蓄文本文书档案的表 TextFiles 是还是不是留存,若不设有,则创制它。然后通过查询表 TextFiles 剖断文本文书档案是或不是存在,若存在,则当前操作为更新操作,程序将实行一条 SQL 语句,对近年来文本文档进行翻新。若不设有,则取当前最大文书档案 id 并加 1作为新文书档案的 id,并奉行一条 SQL 语句,将文书档案音信,包涵文书档案id,以及标题和内容插入到数据库中,并于插入操作截至后的回调方法中,利用 createFileIcon 方法在桌面上为新文书档案创造三个文书档案Logo。清单 14 显示了 createFileIcon 方法的切切实实经过。
清单 14. 创办理文件书档案Logo
 
function createFileIcon(fileId){
     var iconHolder;
     for(var i=壹;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 首先在桌面中寻觅3个空的 div,然后创制三个文档Logo,并将其填充至 div。文书档案Logo有1个 id 属性对应文档id。最终为文书档案Logo增加点击事件管理函数,当点击文书档案Logo时,会首先打开记事本,然后遵照文书档案Logo的 id 查询数据库,提取文书档案的标题和剧情开始展览展现。
图 捌 展现了成立后的文本文书档案,点击后的效益如图 七所示。皇家88登陆手机版 21
图 8. 文本文档
时钟
系统提供了3个简约的电子原子钟用以呈现当前光阴,它由叁个表盘以及分针和时针组成,能够随着岁月的更改动态地转移。今后的 web 应用使用 JavaScript 或 Flash 完结此类功能,其复杂总之。借助 HTML5 的 draw API,能够轻巧地画出所需的图片,相当大的造福了此类应用的营造,此外,HTML5还提供了从前 JavaScript 不可能支撑的四线程编制程序,大大提升了 web 应用的交互性和丰硕性。
石英表有2个主导的表盘,它仅是1副轻巧的图纸,如图 玖 所示。
图 9. 表盘皇家88登陆手机版 22

                    //管理格外情况:在最上/上边MOVE时不境遇现成DIV的情形下,又回来起初拖拽的列最上/下方
                    var tmpColId;
                    for (c = 0; c < dragTbl.rows[0].cells.length; c ) {
                        for (k = 0; k < dragTbl.rows[0].cells[c].getElementsByTagName("DIV").length; k ) {
                            if (dragDiv.id == dragTbl.rows[0].cells[c].getElementsByTagName("DIV")[k].id) {
                                tmpColId = c;
                                break;
                            }
                        }
                    }
                    var tmpPosFirstChild = Common.getElementPos(Common.firstChild(dragTbl.rows[0].cells[tmpColId], "DIV"));
                    var tmpPosLastChild = Common.getElementPos(Common.lastChild(dragTbl.rows[0].cells[tmpColId], "DIV"));
                    var tmpObj = { colId: tmpColId, firstChildUp: tmpPosFirstChild.y, lastChildDown: tmpPosLastChild.y Common.lastChild(dragTbl.rows[0].cells[tmpColId], "DIV").offsetHeight };

在表面之上,建有三个 canvas( 画布 ),如清单 1伍 所示。
清单 15. 画布
1
<canvas id="canvas" width="128px" height="128px"></canvas>
接下去,清单 壹7将在画布上模拟出时钟以及分针,在那前边,额外部须求要二个后台线程用以总结时间,它被定义在名称叫time.js 的独立脚本文件中,如清单 16 所示。
清单 1陆. 后台线程
 
onmessage = function(event)
 {
 //var i = 1;
    setInterval(function() {
    //i ;
    postMessage("");
    }, 60000);
 };
每过 60 分钟,后台线程将会上前台线程发送三个空音讯,以告知前台线程有 60 分钟已经过去了。
清单 一七. 前台线程的开首化
 
var canvas = document.getElementById("canvas");
 if (canvas == null) 
 return false; 
 var context = canvas.getContext('二d');// 那是1个贰维的图像
 context.lineWidth = 2;
 context.translate(6四, 6四);// 定义原点
 
 // 开首化分针
 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,并设置表盘宗旨为坐标原点。然后,获取超越天子,计算分针当前所应指向的坐标,然后从原点出发,画出分针。对于时针,若系统为 二四 小时制,要求首先转化为 1二 小时制,此后的管理类似于分针。
接下去,必要将前台与后台线程联系起来,利用 HTML5提供的多线程编制程序方法,注明 Worker 对象作为后台线程的代办,并使用 onmessage 事件,对后台线程发出的新闻进行拍卖。
清单 1八. 前台线程的 onmessage 事件
1
var worker = new Worker("js/timer.js");
 
 worker.onmessage = function(event){
 
    context.clearRect(-64, -6四, 12八, 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,然后再一次赢稳当前时光,计算分针以及时针对应的坐标,并再次画出时针和分针,从而成就对分针以及时针的立异,最后,每过 一 分钟,表盘更新三回,从而模拟出动态时针的机能,如图 10所示。皇家88登陆手机版 23
图 10. 时钟
离线帮衬
虽说 Web 操作系统的亮点是能够利用网络随地随时进行访问。不过在无法访问网络的情形下,Web 操作系统便无计可施发挥功效。由此 Web 操作系统有必要在离线状态下,仍可以对有些应用及其职能拓展支撑。事实上,各类浏览器已提供了五光十色的缓存机制以提供对离线应用的支撑,然后这个缓存机制往往是暂且的,不可控的。HTML伍为开发职员提供了消除此难点的另1种渠道,它提供了1种永世性的,自定义的缓存方法,使得 Web 操作系统能够在离线的风貌下,仍旧协助部分使用的职能。
HTML5离线支持的中坚是两个缓存清单,个中列出了亟待缓存的公文,本系统中的缓存文件 index.manifest,如清单 1九 所示。
清单 1玖. 缓存清单
 
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 一.拾标示了本文件的版本。
CACHE 之后所列项支出的则是开采人士自定义的始末,个中富含了具备在离线状态下用户访问应用程序所必备的文书。
缓存清单定义甘休后,在 index.html 中插入这么些清单文件名,这样,当浏览器加载这些页面包车型地铁时候,会活动缓存清单文件中所罗列的公文。
清单 20. 应用缓存清单
1
<html manifest="index.manifest">
值得壹提的是,若要援助离线缓存,除客户端浏览器的辅助以外,服务端的支撑也是不可或缺的,就本系统所选拔的 tomcat 来说,须要在其安插文件 web.xml 中加多清单 贰1 所示的条约。
清单 贰一. 劳务器端缓存配置
 
<mime-mapping>
 <extension>manifest</extension>
 <mime-type>text/cache-manifest</mime-type>
 </mime-mapping>
末了,禁止使用本地机械的互连网,重新展开浏览器并访问 Web 操作系统所在的网站,系统中的超过10分之5应用程序还是得以符合规律干活,如图 1一所示。皇家88登陆手机版 24   

                    //保存当前可拖拽各容器的所在地方
          dragObj.dragArray = dragObj.RegDragsPos();

Web 操作系统有着古板操作系统不能比拟的优势,如能够任何时间任何地方使用其余极端进行走访,数据保存在劳务器端,空间越来越大,数据安...

                    //插入虚线框
                    var dashedElement = document.createElement("div");
                    dashedElement.style.cssText = dragDiv.style.cssText;
                    dashedElement.style.border = " dashed 2px #aaa ";
                    dashedElement.style.marginBottom = "6px";
                    dashedElement.style.width = dragDiv.offsetWidth - 2 * parseInt(dashedElement.style.borderWidth) "px"; //减去boderWidth使虚线框大小保持与dragDiv1致
         dashedElement.style.height = dragDiv.offsetHeight - 2 * parseInt(dashedElement.style.borderWidth) "px"; //加上px 保证FF正确                   
          dashedElement.style.position = "relative";
                    if (dragDiv.nextSibling) {
                        dragDiv.parentNode.insertBefore(dashedElement, dragDiv.nextSibling);
                    }
                    else {
                        dragDiv.parentNode.appendChild(dashedElement);
                    }
                    //拖动时成为absolute
                    dragDiv.style.width = dragDiv.offsetWidth "px";
                    dragDiv.style.position = "absolute";

                    dragObj.moveable = true;
                    dragDiv.style.zIndex = dragObj.GetZindex() 1;

                    var downPos = Common.getMousePos(ev);
                    dragObj.tmpX = downPos.x - dragDiv.offsetLeft;
                    dragObj.tmpY = downPos.y - dragDiv.offsetTop;

                    if (Common.isIE) {
                        dragDiv.setCapture();
                    } else {
                        window.captureEvents(Event.mousemove);
                    }

本文由68399皇家赌场发布于最新解决方案,转载请注明出处:皇家88登陆手机版:JS仿iGoogle自定义首页模块拖拽

关键词: 68399皇家赌场 HTML5

最火资讯