(英文转载)最热门的HTML5教程

Most Wanted HTML 5 Tutorials

Posted by Jillz on January 18th, 2010

 

原文地址:http://smashingwebs.com/ p=217

 

 

We just got some fabulous CSS3 tutorials.. Now all you need is to have some HTML 5 Tutorials. HTML 5 is the most modern version of Html that you must learn. So here I have them for you guys.. :) I hope this will help you to understand more. Your comments are very essential for my improvement. So Kindly do comment here.

1. Create a simple web page layout with HTML 5!

2. HTML 5 Visual Cheat Sheet by Woork

3. Web Designers’ Browser Support Checklist

4. webOS HTML5 Database Storage Tutorial

5. HTML5 Doctor, helping you implement HTML5 today

6. Rounded corners on HTML 5 elements

7. Designing a Blog with HTML5

8. HTML 5 Cheat Sheet

9. Designing a Blog with HTML 5

10. Coding an HTML 5 Layout From Scratch

11. Preparing for HTML 5 with Semantic Class Names

12. HTML 5: Nav Ambiguity Resolved

13.  A Basic HTML 5 Tutorial To Show Simple Page Structure

14. HTML 5 Visual Cheat Sheet by Woork

15. HTML 5 Pocket Book

You can also suggest some nice HTML 5 tutorials if you have some. Lets make it large :)

 

html5新特性介绍之PageVisibilityAPI

   在HTML5的众多新特性中,有的新特性可能容易被人忽视,又或者不是主流新

特性,但不可忽略,因为估计以后越来越多浏览器支持.今天要介绍的,就是

chrome和ie 10都支持的一个很好的新特性:HTML5中的PageVisibility API,下面例

子讲解下.

   比如在web中,有的时候,用户会经常切换页面,把某个页面最小化后,可能很久时间都不打开某个页面了,要过很久再打开.又或者比如在浏览器中,会打开很多TAB同时,有时WEB应用

甚至想清楚了解用户究竟打开某个页看了多长时间,这个在以往,可能很难去做到(特别是判断

用户最小化或者切换了其他页的TAB).但现在HTML5中,提出了相关的规范API,叫

pagevisibility api,其WC3的规范在如下连接可以找到描述:

http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html

   其中,DocumentVisibility是其接口,有两个属性:document.hidden和

document.visibilityState.

1)document.hidden属性:

     当用户隐藏了页面或者最小化时,该属性返回true

2)document.visibilityState

    返回当前页面的状态,分别为hidden(隐藏不可见),visiable(可见),preview(标准中认为是可选的,暂时没浏览器实现).

    我们先来看个具体的例子,请用chrome去浏览:http://www.samdutton.com/pageVisibility/

    这里例子中,当你新增加了一个TAB时,会发现音乐和动画停止了,当你再次切换回去

时,动画又会继续了,是不是很有趣呢 

     再来看具体的例子,代码如下:

<!DOCTYPE HTML>  
<html>  
<head>  
     <script type="text/javascript">  
          timer = 0;  
          function onLoad(){  
               document.addEventListener("visibilitychange",stateChanged);  
               document.addEventListener("webkitvisibilitychange", stateChanged);  
               document.addEventListener("msvisibilitychange", stateChanged);  
          }  
          function stateChanged(){  
               console.log(document.webkitVisibilityState);  
               if(document.hidden || document.webkitHidden || document.msHidden){  
                    //new tab or window minimized
                    timer = new Date().getTime();  
               }  
               else {  
                    alert('You were away for ' + (new Date().getTime()-timer)/1000+ ' seconds.')  
               }  
          }  
     </script>  
</head>  
<body onLoad="onLoad()">  
</body>  
</html>

    在上面的代码中,同样,在CHROME运行下,在LOAD事件中,监听了相关的

webkitvisibilitychange事件(这个在CHROME下),如果是IE 10,则是

msvisibilitychange事件,然后在回调函数中,开始了计算用户在页面停留的时间,

所以当你打开其他TAB页或者最小化后,再切换回原来这个页,则会JAVASCRIPT

弹出显示:你离开了页面多长时间

    要注意的是,在CHROME中,属性命名为webkitHidden,事件为 webkitvisibilitychange事件,而在IE 10中,属性为msHidden 和

msVisibilityState.

   参考资料:http://blogs.msdn.com/b/ie/archive/2011/07/08/using-pc-hardware-more-efficiently-in-html5-new-web-performance-apis-part-2.aspx

    http://code.google.com/chrome/whitepapers/pagevisibility.html

AJAX到底带给了我们什么?

我是一个坚定的B/S的支持者,我也深信不疑Web将会统治未来,成为未来90%以上的信息发、布获取渠道[有人也许会说那是电视报纸,报纸我不敢攻击,不过电视未来很可能是IPTV)。未来大家不会在意操作系统这个平台,大家不会去争论你用Windows,我用Mac,他用Linux(虽然我用过两年的Linux并且很喜欢它,不过它真的对普通用户难有吸引力),或者是她用iPhone/gPhone。这些都不重要,重要的是我们都可以通过Web获取信息,获得应用。如果说未来有一个平台,那就是IP/HTTP/WEB/Browser。

 

      回想一下在AJAX流行之前的网页是什么样子的?可能大家不记得了,其实我也不记得了。不过那时候很难想象Web应用可以做到今天这种程度。虽然Web应用还是比桌面应用的交互性差,可是现在可以说使用起来已经很方便了。我觉得Google Office, Gmail这些应用的可用性,基本上我觉得可以称的上不错了。这些,其实都要感谢AJAX在背后的贡献。那么AJAX到底给我们带来了什么呢?

 

       通过这一个多月的开发经历,我深刻体会到AJAX给了你一种能力,让你的Browser表现的像一般地客户端,和服务器交互;不,还给了你一种全新的方式,来思考设计和开发你的Browser应用。其实,只不过以前我们做CS开发的时候,Client我们是跑在操作系统或者虚拟机上的,和服务器之间一般跑着私有的自己设计的协议。很多都是直接在Socket/TCP之上自己设计的协议。而AJAX,给了我们一种方法,让我们的Client跑在Browser里面,协议是在HTTP上自己设计的私有协议。

 

       也许,在开发方式上观念的转变远没有设计角度转变那么深远,我觉得AJAX带给我们的是一种全新的视角去设计我们的Web应用。随着JS框架对AJAX越来越强大的支持,我们可以将更多的精力放在用户体验上面。其实这就是AJAX或者说Web2.0的初衷,用户的体验。也是所有做软件人的终极目标,给人们更好的体验。

 

       也许空说大家没有什么感性的认识,那么我们来举个例子。我们有个简单的应用,就是要呈现给客户他的聊天记录。我们看过很多聊天记录的展现方式。譬如QQ/MSN,不过我发现他们有个共同的问题,就是是以Message为单位的。这样做固然很简单,可是,可是其实每条消息它都是有上下文的,所以最好的方法是以Conversation的方式来展示聊天记录。每个Conversation有参加者,时间(开始时间就可以了),Tag(Label)。然后你点开每个Conversation条目,就可以看到这个Conversation里面的聊天记录。如果是以前,我们可能需要每次点击Conversation条目,然后就需要后台返回一个新的页面。这样速度慢,流量大不说,关键是每次刷新的那种感觉对用户很糟糕。而有了AJAX,我们把所有的Conversation条目存在内存中,用户点击一个条目,通过AJAX获得这个Conversation的Message,然后存到内存中,然后展现给客户(我们可以用很漂亮的动画展现)。当客户点击下一个Conversation条目的时候,上一个条目的Message仍然保存在内存中,下一次如果它再点这个条目的时候,我们就不需要到服务器去取了。[当然要注意内存耗费太大的问题,可以定期清理]      

 

       不过AJAX也有一些缺点。首先就是复杂,大家可别小看这个缺点,复杂就意味着更容易犯错误,更多的Bug,对老板来说就意味这要花更多的Cost;其次就是不能滥用。这有两方面的意思。一就是不要一个页面N多地方都不定时的给后台发送请求,你可以重构这样的设计;二就是要让AJAX真得提高用户的体验,而不是你在那里眩酷,这没有意思;三,我们是在浏览器里面做东西,和客户端还是不一样。譬如一个case,有些应用客户端需要注销。如果你自己做得Client,你可以在点击关闭按钮的时候,做注销的事情。如果服务器那边返回注销成功,你就让客户端退出;如果不成功,你就可以让客户端再注销一次。可是这个在Browser里面你就不可能了,客户关闭窗口,你是可以得到Window.onunload事件,可是你没有机会去判断你的结果;最后一个缺点也是天然的缺点,Http是单向的,也就是服务器没办法以中断的方式给Browser发消息(我知道AJAX PUSH, COMET, Web Socket,可是他们本质上还是单向的Http)。

 

         接着这篇文章,我想说,可能未来Flash/SilverLight, WAP这种过度产品也会go to hell。HTML5(据说还要10年,不过我觉得有Google在,估计4年左右会现端倪)会是我们的未来。

 

 

用Flash的API写html5应用

在大量开发人员不断争论什么html5是否能代替Flash的时候,haXe社区的疯子们搞出了一个让html5控们瞠目结舌的东西——Jeash。仅仅
凭名字,你可能无法了解这个东西究竟是做什么用的,它的功能是——把haXe编写的Flash9以上版本程序编译成html5+js的应用!由于haXe
的Flash9 API与AS 3绝大部分完全相同,这意味着Flash开发人员将不用在理会html5会否替代Flash了。

说到这个
东西,还得把时间回溯到2008年,由于Apple教主乔布斯坚决不肯在Iphone中支持Flash,于是haXe社区的用户们另辟蹊径,先后开发了
nme、neash和hxcpp三个子项目。前两者的功能是让用户把Flash类转换为针对neko的可视化类,实现在nekovm中完全重现Flash
的大部分功能,而hxcpp项目则将针对neko的类转换成了C++类,从而实现了将haXe写的Flash应用源码编译成C++源码,并调用VC、
xcode或gcc等编译器编译成本地代码,由于可以开启opengl支持,hxcpp编译的本地应用运行速度几乎达到极限。同时,亦可将其直接编译为
Iphone可用的应用。该项目的完善版本在2008年末发布,并部分整合到了haXe中。这比Flash
CS5的Iphone输出功能早了半年多!并且至今为止,其开发的应用运行效率仍然比Flash CS5高得多。

以上说的并不是今天的重
点,重点是:相同的技术,也被应用到了HTML5和Javascript上,通过安装扩展库和修改编译参数,我们就可以把大部分haXe编写的Flash
应用源码直接编译为js文件。引用到html中后,即可显示出一个与Flash几乎完全相同的Canvas渲染结果(包括动画)。并且同样的源码,只要修
改编译参数,并且配置好相关环境(主要是C++编译器),就可以编译为Flash程序和C++程序

下面,我们来看一下Jeash的神奇魔法:

首先,下载安装haXe。去http://haxe.org/download
下载。

然后,安装一个叫做mercurial的东东,windows用户到 http://mercurial.selenic.com/downloads/
下载。Linux和MAC用户可以直接在软件源中安装,用apt-get、yum或darwinports安装即可。

最后,用hg软件下载复制jeash的源码库:hg clone http://mercurial.intuxication.org/hg/jeash

接下来,我们打开文本编辑器,复制下面的源码,并保存到一个单独的文件夹中,命名为App.hx文件(下面的代码保存目录相同):

  1. import flash.Lib;
  2. import flash.display.Shape;
  3. import flash.display.Sprite;

  4. class App extends Sprite
  5. {
  6. static function main ()
  7. {
  8. var ellipse:Shape = new Shape();
  9. ellipse.graphics.beginFill( 0xFF9900, 1 );
  10. ellipse.graphics.lineStyle( 0, 0xCCCCCC );
  11. ellipse.graphics.drawEllipse( 40, 40, 100, 60 );
  12. ellipse.graphics.endFill();

  13. var app = new App();
  14. app.addChild( ellipse );
  15. Lib.current.stage.addChild( app );
  16. }
  17. }

复制代码

上面的源码是不是很熟悉?除了flash.Lib类是haXe特有的外,静态的main函数做为程序入口与C/Java等语言类似,其他的都和AS 3没什么区别。

接着,我们把下面的代码保存为app.html文件:

  1. <html>
  2. <head>
  3. <title>My first Jeash example</title>
  4. </head>
  5. <body>
  6. <div id=”haxe:jeash” style=”width:150px; height: 150px”></div>
  7. <script type=”text/javascript” src=”./app.js”></script>
  8. </body>
  9. </html>

复制代码

然后是保存以下的build.hxml文件,这个是编译参数文件:

  1. –remap flash:jeash
  2. -js app.js
  3. -main App
  4. -cp jeash

复制代码

最后,把hg下载回来的源码,同样拷贝到这个目录中(是里面含有一个叫做Html5Dom.hx的文件的那个jeash目录)。

下面就可以编译了:

在命令行中进入这个目录,输入: haxe build.hxml 回车。再次看到命令行的时候,就是编译成功,如果有其他提示信息,八成是出错了。有时编译可能出现以下的错误:

jeash/jeash/display/DisplayObjectContainer.hx:270: characters 3-6 : Unknown identifier : Lib

解决方法是打开这个文件,在 import flash.geom.Point; 这一行下面增加一行代码:import flash.Lib;


译成功后,在这个目录下,你会发现多了一个app.js文件,就是上面的app.html文件中引用的那个。接下来,在Firefox
4或Chrome中打开app.html文件,就可以看到结果了(我的Firefox
3.6.13也能看到一个结果,但貌似由于支持的不好,看不到曲线)。

源码如下:

test.tar.gz


(157.57 KB)

html5百度技术沙龙

今天下午参加了百度关于html5的技术沙龙。嘉宾主要就html5 canvas, svg技术,基于html5的应用、移动应用、游戏开发进行了分享,发现参与者当中有不少创业的公司和人员,html5在国内的发展看来有一定规模和基础。会议当中一个比较让我注意的是一位头发已经谢顶的“大叔”,是古典红木家具的一个负责人,他跟各技术宣讲嘉宾都很主动交流,如询问svg、矢量图在家具的互联网展示上的一些问题等等。如果html5的应用不局限于一些纯粹的技术追求、或者仅仅将目光放在游戏上,相信在国内的发展会更好,或者是我还没有看到,孤陋寡闻了,希望有更多这方面的分享。

 

javaScript广度优先搜索法“;自动推箱子“;(二)

接上文: javaScript 广度优先搜索法”自动推箱子”(一)http://128kj.iteye.com/blog/2078626

代码第二部分。Test-4.html

<!DOCTYPE html>

<html lang=”zh”>

  <head>

   <meta charset=”gbk”>

   <title>推箱子AI</title>

   <script src=”Storehouse.js”></script>

</head>

<body>

<h3>当前分析的状态</h3>

<div id=”state”></div>

<h3>从当前状态产生的一个新状态</h3>

<div id=”msg”></div>

</body>

</html>

<script>

var playerPos={x:5,y:5};//人开始坐标

   

        //第四关地图数据http://www.108js.com

        var map= [[“1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”],

                 [“1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”],

                 [“1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”],

                 [“1”, “1”, “1”, “1”, “1”, “#”, “#”, “#”, “#”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”],

                 [“1”, “1”, “1”, “1”, “#”, “#”, “.”, “.”, “#”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”],

                 [“1”, “1”, “1”, “1”, “#”, “S”, “B”, “.”, “#”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”],

                 [“1”, “1”, “1”, “1”, “#”, “#”, “B”, “.”, “#”, “#”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”],

                 [“1”, “1”, “1”, “1”, “#”, “#”, “.”, “B”, “.”, “#”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”],

                 [“1”, “1”, “1”, “1”, “#”, “T”, “B”, “.”, “.”, “#”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”],

                 [“1”, “1”, “1”, “1”, “#”, “T”, “T”, “Y”, “T”, “#”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”],

                 [“1”, “1”, “1”, “1”, “#”, “#”, “#”, “#”, “#”, “#”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”],

                 [“1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”],

                 [“1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”],

                 [“1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”]];

var dx = [-1, 1, 0, 0];//人有四个方向可移动,下,上,右,左

var dy = [0, 0, 1, -1];

var tempmap=null;//临时的地图数据

var Queue=[]; //队列,保存程序中产生的推箱子状态

var allstate=[];//保存所有状态,用于判断重复

var finish=false;//是否结束

var state=new Storehouse(playerPos,map,null,””,0);//最初状态,参数有:人的位置,地图,父状态,来到此状态的路径和步数

var state1=state;//保存最初状态

allstate.push(state);//最初状态加入数组

function isExist(sta){//判断数组allstate中是否存在sta

      for(var i=0;i<allstate.length;i++)

         if(allstate[i].equals(sta))

            return true;

     return false;

  }

function Dfs() {

   Queue.unshift(state);//最初状态进队列http://www.108js.com

     while (Queue.length!=0) {

        state = Queue.pop();//从队列中出队的节点

        document.getElementById(“state”).innerHTML=state.toString();

        // 从“人”可走的四个方向上下右左分析队列中弹出的状态”);

        for (var i = 0; i < 4; ++i) {

            switch(i){

              case 0:

                movePlay(state,-1,0,”u”);

                break;

              case 1:

                movePlay(state,1,0,”d”);

                break;

              case 2:

               movePlay(state,0,1,”r”);

               break;

              case 3:

               movePlay(state,0,-1,”l”);

               break;

            }          

            if(finish){//如果找到了答案

              return;

            }

          }

       }

     return false;

  }

function movePlay(state,m,n,direc){ //移动玩家,m行,n例,参数为偏移量

        var player=state.getPlayerPos();//玩家的位置

        var tempmap=copyArray(state.getMap());//克隆地图

        var ts=null;

        //人物的下一个位置

        var tempPos ={x:0,y:0};

        //箱子的下一个位置

        var boxPos ={x:0,y:0};

        tempPos.x=player.x+m;

        tempPos.y=player.y+n;

      

        if(!state.isOk(tempPos)) return;//位置出界

        var playerMap = tempmap[tempPos.x][tempPos.y]; //人物位置地图数值

        //人物的下个位置不能是石头,如果是,什么也不做。

        if(playerMap!=”#”){

            //人物碰到箱子或处在目标点上的箱子

            if(playerMap==”B”||playerMap==”Y”){

                 boxPos.x = tempPos.x+m;

                 boxPos.y = tempPos.y+n;

                 if(!state.isOk(boxPos)) return;

                 var boxMap = tempmap[boxPos.x][boxPos.y]; //箱子位置地图数值

                //箱子的下一位置不能是石头或箱子

                if(boxMap!=”#” && boxMap!=”B” && boxMap!=”Y”){

                    //先箱子移动

                    if(boxMap==”.”){//空地

                        tempmap[boxPos.x][boxPos.y] =”B”;

                    }else if(boxMap==”T”){//成功推了一个箱子

                        tempmap[boxPos.x][boxPos.y] = “Y”;

                    }

                    //再移动人

                    if(playerMap==”Y”){

                        tempmap[tempPos.x][tempPos.y] =”Z”;//碰到在目标点上的箱子,变成人在目标点上

                    }else{

                        tempmap[tempPos.x][tempPos.y] = “S”;//人到箱子的位置

                    }

                  

                   if(tempmap[player.x][player.y]==”Z”){//人原来在一个目标点上

                       tempmap[player.x][player.y]=”T”;//人的原来位置设为目标点

                    }

                    else {

                        tempmap[player.x][player.y]=”.”;//人的原来位置设为空地

                    }

                     ts=new Storehouse(tempPos,tempmap,state,state.getPath()+direc.toUpperCase(),state.getStep()+1);//新状态

                 

                      if(ts.isWin()){ //判断新状态是否完成任务,return;否则

                           document.getElementById(“state”).innerHTML=state1.toString();

                           document.getElementById(“msg”).innerHTML=ts.toString();

                           document.write(“胜利完成任务<br>”);

                           document.write(“推箱子路径为:”+ts.getPath()+”<br>”);

                           document.write(“所用步数为:”+ts.getStep()+”<br>”);

                          finish=true;

                          return;

                       }

                    

                       if(!ts.isBlock(new Array(),boxPos.x,boxPos.y)&&!isExist(ts)){ // 分析此状态是否是死的或已经存在”)

                         //产生了一个新状态;

                          document.getElementById(“msg”).innerHTML=ts.toString();

                          allstate.push(ts);//保存此状态

                          Queue.unshift(ts);//进队列

                       }

                }

            }else{//人物碰到空地或碰到目标点http://www.108js.com

                   if(tempmap[player.x][player.y]==”Z”){//人原来在一个目标点上

                       tempmap[player.x][player.y]=”T”;//人的原来位置设为目标点

                       if(tempmap[tempPos.x][tempPos.y]==”T”)//

                         tempmap[tempPos.x][tempPos.y]=”Z”;//人在目标点上

                       else  tempmap[tempPos.x][tempPos.y]=”S”;//新的地图数据设置为人

                    }else if(tempmap[player.x][player.y]==”S”){//人的原来位置

                       tempmap[player.x][player.y]=”.”;//人的原来位置设为空地

                       if(tempmap[tempPos.x][tempPos.y]==”T”)//

                         tempmap[tempPos.x][tempPos.y]=”Z”;//人在目标点上

                       else  tempmap[tempPos.x][tempPos.y]=”S”;//新的地图数据设置为人

                    }

                   

                 ts=new Storehouse(tempPos,tempmap,state,state.getPath()+direc,state.getStep()+1);//产生一个状态

                 if(!isExist(ts)) {

                    //新状态

                    document.getElementById(“msg”).innerHTML=ts.toString();

                    allstate.push(ts); 

                    Queue.unshift(ts);//进队列

                }

            }

        }

        //人的下个位置是石头

  }

   //克隆二维数组

    function  copyArray(arr){

var b=[];

for(i=0;i<arr.length;i++)

{

b[i]=arr[i].concat();

}

return b;

    }     

  Dfs();

</script>

最后给出源码下载。欢迎批评指正。

欢迎访问博主的网站:http://www.108js.com

强大的HTML5

        前些天看了一些HTML5方面的资料,感觉的确很强大,firefox和chrome目前已经支持了一些特性,例如canvas和本地存储等等,今天花了一个晚上的时间实践了一把canvas,做了一个比较简单的web版的贪吃蛇,开发起来的确还是挺方便的,就像当年用TurboC做贪吃蛇的感觉差不多。

        网上最近好像很多文章都在讨论,HTML5是否会取代Flash,之前没接触过的时候一直以为HTML和Flash并没有可比性,但通过对HTML5的了解,改变了这种观点,HTML5的亮点很多,光是canvas、本地存储和web socket这几个特性,就能够做很多以前做不到的功能,想想看,使用canvas可以定制我们需要的界面甚至各种交互的控件,本地存储解决了以前脚本无法访问本地文件只能使用cookie保存数据的问题,web socket在网络游戏等方面更是可以发挥作用。所以现在感觉,HTML5替代Flash并非不可能,只要解决浏览器的兼容性问题和性能问题,Flash基本上就可以ByeBye了。

 

 

http://xiaowei.sinaapp.com/snake.html

实现HTML5的跨浏览器功能(转)

 

最新版本的 HTML 和 CSS 提供了许多新特性。例如,HTML5 包含了让 Web 页面更有语义的新元素;现在,您可以离线储存数据、创建可编辑的内容区和使用拖放功能等等。使用 CSS3 可以创建未使用图像的圆角效果、添加阴影和渐变。尽管有许多新特性已经可用,但是并不是所有新特性能够跨浏览器工作。对于本文提供的特定 HTML5 和 CSS3 技巧,您现在就可以在所有主流浏览器的最新版本上使用它们,包括 Apple Safari、Windows  Internet Explorer 、Mozilla Firefox 和 Google Chrome。

尤其是某些版本的 Internet Explorer,它们需要一些帮助才能识别新的 HTML5 元素。幸运的是,一个名为 html5shim 的公开可用 JavaScript 文件(一个支持 HTML5 Internet Explorer 的脚本)能够帮助 Internet Explorer 识别和呈现 HTML5 元素,这是 Internet Explorer 本身无法实现的功能。要包含这个 JavaScript 文件,仅需将 清单 1 中的代码放入到 HTML 文件中正在使用的 CSS 之上的<head> 部分中。

清单 1. html5shim,一个支持 HTML5 Internet Explorer 的脚本

 

<!--[if lt IE 9]>
<script type="text/javascript" src="http://html5shim.googlecode.com/svn/trunk/
html5.js"></script>
<![endif]-->

 这段代码还能够防止不需要该代码的浏览器加载它,因此仅 Internet Explorer 8 或更早的版本能够加载该代码。您可以通过访问项目的网站更多地了解这个 JavaScript 库(参考资料 部分提供相关链接)。

HTML5

HTML5 除了引入许多新元素之外,它的新功能也格外引人注目。这个小节将讨论 HTML5 的一些新元素,并展示如何创建可编辑的内容区和在多个页面之间发布消息。

页面结构

如果您花大量时间来设计 HTML 网站的结构,您将发现有许多部分是重复使用的。常见的是用于显示 logo 或其他标识信息的页头、列出网站板块的导航部分和用于显示版权信息的页脚。在以前的 HTML 版本中,通常使用 id 属性来识别这些元素;例如,页头包含在 id 设置为 "header" 的 <div> 中,即 <div id="header">

对于 HTML5 时,您可以使用新的标记来等义这些特定的区域,而不需要编写额外的标识属性。例如,使用新的 header 元素代替带有页头 id 的 <div>。这不仅是更加合理的代码使用方法,而且还对查看其他开发人员的 Web 页面非常有用,因为许多开发人员都使用不同的代码编写方式。当然,在许多情况下 id 属性仍然很有用,但这些常用的元素不必要再使用它。清单 2 是一个基础的 HTML5 页面例子,它使用了 headernavsectionarticleaside 和 footer 元素。

清单 2. 基础的 HTML5 页面结构

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
	<title>Cross-browser HTML5 and CSS3</title>
    <!--[if lt IE 9]>
    <script type="text/javascript" src="http://html5shim.googlecode.com/svn/trunk/
	html5.js"></script>
    <![endif]-->
</head>
<body>

	<header>
		<nav>
			<!--Navigation-->
		</nav>
	</header>
	
    
    <section id="intro">
        <header>
            <h2>Cross-browser HTML5 and CSS3</h2>
        </header>
        <div>Lorem ipsum</div>
    </section>
    
	<section id="content">
        <section id="articles">
            <article>
                <header>
                    <h2>Article title</h2>
                    <p>Posted on <time datetime="2009-09-04T16:31:24+02:00">
					September 4th 2009
					</time></p>
                </header>
                <div>Pellentesque habitant morbi tristique senectus et netus et 
				malesuada fames ac turpis egestas.</div>
                
                <h2>Comments</h2>
                <form id="comment-form">
                    <input type="text" name="comment" id="comment" />
                    <input type="submit" value="submit" />
                </form>    
            </article>       
        </section>
    
        <aside>
            <h2>About section</h2>
            <p>Donec eu libero sit amet quam egestas semper. Aenean ultricies mi 
			vitae est. Mauris placerat eleifend leo.</p>
        </aside>
    </section>

	<footer>Copyright notice</footer>

</body>

</html>

 每个元素的意思都相当简明易懂,但有几点需要说明:

  • HTML5 仅有一个 doctype:<!doctype html>
  • headernav 和 footer 都是我们能意料到的。
  • 可以使用 section 元素来帮助定义 Web 页面布局的各个部分,例如一篇文章或一则介绍。
  • 可以使用 article 元素来标识单独的博客帖子和评论等。
  • 可以使用 aside 元素作为侧栏;其主要作用是将主页面内容包围起来。

要让 aside 元素出现在主页面内容旁边,请确保它们的宽度都适合当前页面的宽度,然后调整元素的位置。使用浮点数是以前让元素紧挨着排列的常用方式,但有了 section 和 aside 元素之后,您可以使用能够显示值的表格和表单元格代替浮点数,如 图 1 所示。

图 1. HTML5 页面布局

使用 header、intro、section、aside 和 footer 标记的 HTML5 页面布局例子

 

清单 2 展示了如何设置 content 部分使其显示为表,以及如何设置 articles 部分和 <aside> 标记使其显示为表格的单元格。这样这个结构就成为一个表而不需要使用额外的表代码,并且表单元格像列一样彼此紧挨着。清单 3 是一个例子,它展示了如何编写 CSS 来让这些元素紧挨着显示。


清单 3. 显示用的表格值

#content {
	display: table;
}
#articles {
	display: table-cell;
	width: 620px;
	padding-right: 20px;
}
aside {
	display: table-cell;
	width: 300px;
}

 创建可编辑内容区

另一个有趣的 HTML5 特性是 ContentEditable。如 清单 4 所示,任何使用 ContentEditable 属性的元素都变得可编辑。这意味着您可以在元素内部编辑任何文本,而不需要使用繁琐的 form 元素。图 2 是演示 ContentEditable 属性的实际使用的例子。


图 2. 可编辑内容区
使用 ContentEditable 属性实现可编辑内容区的例子 

您可以借助 Ajax 轻松地将任何更新保存到数据库,并且通过 HTML5 的跨浏览器本地存储功能,您可以在离线时使用这个强大的功能。


清单 4. 创建可编辑的 HTML 元素

 

<div id="editable" contenteditable="true">
Pellentesque habitant morbi tristique senectus et 
netus et malesuada fames ac turpis egestas.
</div>

 


发布消息

消息发布是一个带来诸多可能性的新特性。清单 5 和 清单 6 通过例子展示了如何从主 Web 页面将消息发布到该页面的 iframe 中。


清单 5. 发布消息

 

<form id="comment-form">
    <input type="text" name="comment" id="comment" />
    <input type="submit" value="submit" />
    <iframe id="comment-iframe" src="post-message.html"></iframe>
</form>
<script type="text/javascript" src="assets/js/event.js"></script>
<script type="text/javascript">
    var win = document.getElementById("comment-iframe").contentWindow;
    addEvent(document.getElementsByTagName('form')[0], 'submit', function (e) {
        if (e.preventDefault) e.preventDefault();
        win.postMessage(document.getElementById("comment").value, 
			"http://studiosedition.com");
        // otherwise set the returnValue property of the original event to false (IE)
        e.returnValue = false;
        return false;
    });
</script>

 一个名为 postMessage JavaScript 的函数处理实际发布的消息;您可以在 iframe 中使用名为 message 的新事件来获取事件和相关的属性。

清单 6. 获取已发布的消息

 

<p id="post-comment"></p>
<script type="text/javascript" src="assets/js/event.js"></script>
<script type="text/javascript"> addEvent(window, "message", function(e){ 
if(e.origin !== "http://studiosedition.com") { document.getElementById("post-
comment").innerHTML = 'Message from ' + e.origin; } else { 
document.getElementById("post-comment").innerHTML = e.origin + " : " + e.data; } 
}); </script> 

 这个例子使用了一个定制的 JavaScript 事件函数,它作为外部文件 event.js 包含进来。清单 7 显示了该文件的脚本。

清单 7. 定制的事件函数

 

var addEvent = (function () { if (document.addEventListener) { 
return function (el, type, fn) { if (el && el.nodeName || el === window) 
{ el.addEventListener(type, fn, false); } else if (el && el.length) { 
for (var i = 0; i &lt; el.length; i++) { addEvent(el[i], type, fn); } } }; } 
else { return function (el, type, fn) { if (el && el.nodeName || el === 
window) { el.attachEvent('on' + type, function () { return fn.call(el, 
window.event); }); } else if (el && el.length) { for (var i = 0; i 
&lt; el.length; i++) { addEvent(el[i], type, fn); } } }; } })(); 

试用了一下HPtouchPad,有点小失望.

我手里的这台机器是 工程样机. 从样机来看, 这台平板并不出色.

性能不高,重量>ipad, 操作延迟明显,没有什么吸引人的亮点和王牌应用.

我比较关注浏览器很让我失望.

WebOS虽然基于webkit内核构建,但是内置的webkit很不给力,性能不是很高,HTML5得分也不高(使用的safari内核版本为532.2) ,window.devicePixelRatio为1(这个正常,毕竟是非视网膜屏嘛).

另外,很多在其他移动设备上”约定俗成的东西”在它这都没有.例如:不支持touchXXXX事件(需要用其他事件来模拟),window的userAgent里没有mobile字样, 没有window.orientation属性.

由于是公家的东西, 不能进行深度试用, 就简单写这点吧.

不知道最后的正式发布版本会如何.

下面是几张跑我的HTML5游戏引擎的截图:

我的HTML5游戏引擎480*300分辨率的小画面游戏在上面只能跑到35帧, 在ipad上能跑到55.

640*480分辨率的游戏能跑到 25帧(ipad为测试)

HTforWeb自定义3D模型的WebGL应用

Screen Shot 2015-01-07 at 11.53.23 PM

有不少朋友询问《HTML5 Web 客户端五种离线存储方式汇总》文章例子的3D表计模型是如何生成的,这个例子是通过导入3dmax设计好的表计模型,然后通过obj格式导入到HT for Web系统中进行控制,这种方式特别适合复杂模型的应用场景,但对于监控系统的很多应用其实并不需要专业的美工使用专业的3D编辑工具,完全通过HT for Web预定义的和内置自定义3D模型API就能满足很多应用,这里介绍几种场景的自定义3D模型应用。

Screen Shot 2015-01-07 at 11.48.45 PM

上图是采用HT提供的createRingModel函数,通过编辑2D的多边形生成对应的环状的3D模型,对于花瓶碗杯等环形对称的物体很适合采用该函数构建。除了createRingModel外,HT的建模手册中的custommodel自定义模型例子,还采用了createExtrusionModel等更多的自定义模型API构建了一个餐桌椅和墙面的场景,其效果如下:

Screen Shot 2015-01-07 at 11.46.14 PM

HT内置的基础模型也有很多参数可调节设置出多种模型效果,参见HT建模手册的如下例子:

Screen Shot 2015-01-07 at 11.49.56 PM

自定义模型还可用于构建如机房、机框、板卡和端口的常见电信网管监控模型:

Screen Shot 2015-01-07 at 11.50.54 PM

http://v.youku.com/v_show/id_XODY2ODc0ODY0.html

该EMS设备管理系统例子3D模型和Tree组件通过HT强大灵活的模型与图形的数据绑定功能,从而实现树上自定义图标和3D自定义模型的数据共享,实时一致刷新效果,以下为该EMS例子的全部JavaScript代码:

function init(){                                 
	dm = new ht.DataModel();                
	treeView = new ht.widget.TreeView(dm);                                                                                                 
	g3d = new ht.graph3d.Graph3dView(dm);                          
	mainSplit = new ht.widget.SplitView(treeView, g3d, 'h', 0.2);   
	
	view = mainSplit.getView();  
	view.className = 'main';
	document.body.appendChild(view);    
	window.addEventListener('resize', function (e) {
		mainSplit.invalidate();
	}, false);                         

	register2DImage();
	register3DModel();
	addModel(); 
					
	g3d.setGridVisible(true); 
	g3d.setGridSize(30);
	g3d.setGridGap(50);
	g3d.setEye([200, 200, 600]);
	g3d.setCenter([0, 200, 0]);
	g3d.getView().style.background = '#F9F9F9';                 
	g3d.getLabel = function(data){
		return data.s('label');
	};
	dm.sm().setFilterFunc(function(data){
		return data !== wall;
	});
	treeView.setVisibleFunc(function(data){
		return data !== wall;
	});                
	treeView.expandAll();
}

function register2DImage(){
	ht.Default.setImage('ems-frame', {
		width: 18,
		height: 18,
		comps: [
			{
				type: 'rect',
				rect: [5, 4, 8, 11],
				borderWidth: 2,
				borderColor: '#34495E'
			}                         
	]});        

	ht.Default.setImage('ems-pane', {
		width: 18,
		height: 18,
		comps: [
			{
				type: 'rect',
				rect: [0, 4, 18, 10],
				background: {func: 'style@shape3d.color'}
			}                         
	]});     

	ht.Default.setImage('ems-block', {
		width: 18,
		height: 18,
		comps: [
			{
				type: 'circle',
				rect: [0, 2, 18, 10],
				background: {
					func: 'attr@circleColor',
					value: '#3498DB'                               
				}
			}, 
			{
				type: 'rect',
				rect: [4, 14, 10, 3],
				background: {
					func: 'attr@rectColor',
					value: '#3498DB'                               
				}
			}                           
	]});                 
}

function register3DModel(){
	ht.Default.setShape3dModel('ems-frame', ht.Default.createFrameModel(0.1, 0, 0.1, {top: true, bottom: true, back: true}));       

	ht.Default.setShape3dModel('ems-block', [
		{
			shape3d: ht.Default.createCylinderModel(32, 0, 32, false, false, true, true),   
			r3: [Math.PI/2, 0, 0],   
			color: {
				func: 'attr@circleColor',
				value: '#3498DB'
			}     
		},
		{
			shape3d: 'box',
			s3: [1, 0.2, 1], 
			t3: [0, -0.7, 0],
			color: {
				func: 'attr@rectColor',
				value: '#3498DB'
			}
		}
	]);                  
}

function addModel(){
	wall = new ht.Shape();
	wall.setName('Wall');
	wall.setPoints(new ht.List([
		{x: -750, y: 750},
		{x: -750, y: -750},
		{x: 750, y: -750},
		{x: 750, y: 750}
	]));
	wall.setTall(400);
	wall.setElevation(200);
	wall.s({
		'shape.border.width': 5,
		'shape.border.color': 'rgba(20, 20, 20, 0.8)',
		'shape.background': null,    
		'all.color': 'rgba(102, 192, 218, 0.95)',
		'all.transparent': true,
		'all.reverse.cull': true
	});
	dm.add(wall);                                               

	var frame = new ht.Node();
	frame.setName('Main Frame');
	frame.setIcon('ems-frame');
	frame.s3(120, 300, 120);
	frame.p3(0, 152, 0);
	frame.s({
		'shape3d': 'ems-frame',
		'shape3d.color': '#34495E',
		'label': 'www.hightopo.com',
		'label.color': 'white',
		'label.background': '#3498DB',
		'label.position': 6,
		'label.t3': [-6, -54, 6],
		'label.r3': [0, Math.PI/4, Math.PI/2]
	});
	dm.add(frame);                                
	
	var colors = ['#9C8CE7', '#00C59D', '#A741B6', '#F5C700', '#31485F', '#F81F25', '#00B862', '#3B7DA7'];
	for(var i=0; i<6; i++){
		var pane = new ht.Node();
		pane.setIcon('ems-pane');
		pane.setName('Pane' + (i+1));
		pane.s3(108, 16, 8);                    
		pane.s({
			'shape3d': 'box',
			'shape3d.color': '#ECF0F1'
		});
		pane.setHost(frame);
		pane.setParent(frame);                     
		dm.add(pane);
		
		if(i < 2){
			for(var j=0; j<8; j++){
				var block = new ht.Node();
				block.setName('block ' + i + '*' + j);
				block.s3(8, 8, 12);                
				block.p3(-39+j*11, 1, 0);
				block.setHost(pane);
				block.setParent(pane); 
				block.setIcon('ems-block');
				block.s({
					'shape3d': 'ems-block'
				});                       
				if(i === 1){
					block.a({
						'circleColor': colors[j],
						'rectColor': '#00F2CF'
					});
					
				}
				dm.add(block);                                        
			}                     
		}else{
			pane.setName('Pane' + (i+1) + ' [ Empty ]');
			pane.s({
				'shape3d.color': '#BDC3C7'
			});
		}                   
		pane.p3(0, 265-i*27, 54);
	}                
}