html5
HTML5和css3跨浏览器降级兼容方案
html5和css3也火了一段时间了,很多前端潮人也慢慢的给自己的博客什么的加入了html5和css3的应用,实际上像腾讯和淘宝这些大公司的开发人员也在自己负责的项目中加入了一些html5和css3的应用,不管是作为试练还是优化,html5和css3确实带来了不少好处,但其应用的局限性也是显而易见的,那就是市场上存在的各种要死不死的浏览器和使用这些浏览器内核的三方浏览器,他们不支持html5和css3的新特性,但是这部分占浏览器的份额还很大,因此我们一般在做产品的时候不得不顾及这部分用户,所以如果我们一定要应用html5和css3的话,需要做至少两套方案,对于支持html5和css3特性的浏览器使用相应的技术进行处理,而不支持的我们对其优雅降级处理。html5的支持情况可以通过一个js库来检测,想必很多潮人都知道的Modernizr,该站不知道为何华丽的和谐了,请各自翻墙。 Modernizr也给出了html5和css3跨浏览器降级兼容方案,内容包括:canvas,web storage,video,Audio,web sql database,websockets,geolocation,application cache等等,还有css3的一些内容,详细的请访问链接: http://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills
HTML5本地存储
同样是html5的规范,同样是存储,HTML5本地存储和离线存储不是一回事,感觉有必要提及,因为在互联网铺天盖地宣传html5的特性的时候,经常出现这样那样的字眼,对于还没接触的或初学者来说,很容易混淆这两个概念。离线存储(Offline Storage)正如之前我的那篇介绍中你看到的样子,实际上它实现的是文件的离线存储,而本地存储(Local Storage)跟会话存储(Session Storage)一样同属于web的数据存储(Web Storage)。还有一种存储方式是Web SQL Database,它是一个可以用SQL操作的客户端数据库。这些存储方式都是用户客户端实现的,因此有人会把它们称为“本地存储”,实际上我觉得叫“客户端存储”更合适,这样不至于跟Web Storage中的Local Storage概念冲突和混淆。 什么是HTML5 Local Storage? HTML5中介绍的Local Storage(有的地方把它叫做DOM Storage)是一种将web数据存储在用户本地的存储方式,这种形式的存储其实你早就接触过了,那就是cookie。那么为什么不直接用cookie好了,还要本地存储做什么?我们知道,html5带来更丰富的web表现形式,在web中实现大量富媒体应用的时候,对于数据存储的要求也相对提高,当然服务器的压力也相应变大,因此我们需要一种类似于cookie的存储方式,但它和cookie不大一样: 我们需要更大的存储空间,本地存储默认有5MB,而cookie只能存4k的数据 和cookie一样都存储在客户端的 数据不会因为页面刷新或关闭等操作而改变 不会向服务器发出请求,cookie是会包含在每个HTTP请求中的 好吧,假设你现在正需要这样的一种存储方式,那么你要知道浏览器的支持情况如何,支持本地存储的浏览器版本有:IE8+,FIREFOX3.5+,SAFARI4+,CHROME4+,OPERA10.5+,IPHONE2+,ANDROID2+以及其他我不知道的。 如何使用HTML5 Local Storage? 不是所有的浏览器都支持html5的本地存储,所以在使用它之前,你需要一点检测工作,来确保你的应用正常运作,你需要下面的代码:
|
1 |
if('localStorage' in window&&window['localStorage'] !== null){/* do storage stuff... */} |
Local Storage实现了Storage接口,该接口的原型如下: interface Storage { readonly attribute unsigned long length; getter DOMString key(in unsigned long index); getter any getItem(in DOMString key); setter creator void setItem(in DOMString key, in any data); [...]
html5离线存储入门
所有的浏览器都有自己的缓存机制,但那些机制并不可靠而且难以控制,在你做web开发的时候可能经常因为浏览器缓存带来的问题而烦恼不已。html5通过ApplicationCache接口解决了一些问题,并且使离线存储成为可能,离线存储使得你的web应用可以在用户离线的状况下进行访问。这个技术显然至少有三个好处: 最直接的好处就是用户可以离线访问你的web应用 因为文件被缓存在本地使得web页面加载速度提升许多 离线应用只加载被修改过的资源,因此大大降低了用户请求对服务器造成的负载压力 如何实现离线文件存储? 你的服务器得先支持html5!是的,这句话看上去像是以前在css森林群里大家说的“我的服务器不支持div+css”一样的玩笑话。但我很严肃的告诉你,要实现离线存储的应用,你确实需要服务器的支持!容我细细道来,先来看看html5的离线文件存储应用对你的代码有什么要求,你需要在页面的html标签中通过manifest属性引用一个manifest文件来使得你的应用可缓存。简单地说,manifest文件是一个文本文件,它罗列了离线访问应用时所需缓存的文件清单(注意:引用该manifest文件的页面,不管你有没有罗列到清单中,都会被缓存),但不只是这样。代码像下面这样:
|
1 2 3 |
<html manifest="test.manifest">
...
</html> |
当然,这个manifest的文件路径用绝对路径和相对路径都可以,甚至可以引用其他服务器上的manifest文件。该文件所对应的mime-type应该是text/cache-manifest的,所以你需要配置服务器来发送对应的MIME类型信息,服务器配置不在讨论范围内,请自行去了解吧。接下来要看的是manifest文件的结构,它的结构很简单,我们来看下面的例子:
|
1 2 3 4 5 |
CACHE MANIFEST
index.html
style.css
images/logo.png
scripts/mootools.js |
这是最简单的一个manifest文件的样子,正如前面所提到的,文件罗列了需要被缓存的文件清单,第一行中的CACHE MANIFEST 是必须的,每个站点有5MB的空间来存储这些数据,如果manifest文件或文件里所列的文件无法加载,整个缓存更新过程将无法进行,浏览器会使用最后一次成功的缓存。前面说过manifest文件不只是罗列要缓存的文件,那么它还有其他什么作用呢?让我们来看个稍微复杂点的例子:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
CACHE MANIFEST
# wanz app v1
# 指明缓存入口
CACHE:
index.html
style.css
images/logo.png
scripts/main.js
# 以下资源必须在线访问
NETWORK:
login.php
# 如果index.php无法访问则用404.html代替
FALLBACK:
/index.php /404.html |
有经验的同学一定可以看出来#是用来注释一行的,但它还有一个小作用。web应用的缓存只有在manifest文件被修改的情况下才会被更新,所以如果你只是修改了被缓存的文件,那么用户本地的缓存还是不会被更新的,但是你可以通过修改manifest文件来告诉浏览器需要更新缓存了。利用这点,你可以像上面的例子中那样,写一句这样的注释一个文件版本: # wanz app v1 这样写有三个好处: 你可以很明确的了解离线web应用的版本 通过简单的修改这个版本号就可以轻易的通知浏览器更新 你可以配合JavaScript程序来完成缓存更新 正如你看到的,manifest文件有三个节点,它们各自的含义如下: CACHE: 这个是manifest文件的默认入口,在此入口之后罗列的文件 (或直接写在CACHE MANIFEST后的文件)在它们下载到本地后会被缓存起来 NETWORK: 可选的,在此节后面所罗列的文件是需要访问网络的,即使用户离线访问了也会直接跳过缓存而访问服务器 FALLBACK: 可选的,用来指定资源无法访问时的回调页面。每一行包括两个URI,第一个是资源文件URI,第二个是回调页面URI。 备注:以上描述的这些节是没有先后顺序的,而且在同一个manifest中可以多次出现 到目前为止,你应该了解如何来实现离线文件的存储了,只需要三个步骤:1,配置服务器manifest文件的MIME类型;2,编写manifest文件;3,在页面的html标签的manifest属性中引用写好的manifest文件。 如何更新离线存储? 你做到了,即使拔掉网线你也可以访问你制作的页面。于是你开始兴致勃勃的丰富你的页面,修改JavaScript代码和css来实现更炫的页面效果,然后将它们上传到服务器,结果你会发现:即使你刷新页面刷到爆,清除n次历史访问记录都无法看到你要的新的页面效果。那是因为你根本还没有更新html5的离线存储文件。现在的问题是如何更新html5离线缓存?下面的三种情况可以做到: 用户清除了离线存储的数据,这个不一定就是清理浏览器历史记录就可以做到的,因为不同浏览器管理离线存储的方式不同。比如Firefox的离线存储数据要到“选项”=>“高级”=>“网络”=>“脱机存储”里才可以清除。 manifest文件被修改,上面说的,你修改了manifest文件里所罗列的文件也不会更新缓存,而是要替换manifest文件 使用JavaScript api编写更新程序 前面两种方式很简单,自己折腾吧。我们来看第三种,首先你需要对相关的api有所了解,详细的前往查看:http://www.whatwg.org/specs/web-apps/current-work/#applicationcache 先简单介绍下ApplicationCache和它的几个重点属性及方法: cache = window . applicationCache 返回应用于当前window对象文档的ApplicationCache对象 cache = self . applicationCache 返回应用于当前shared worker的ApplicationCache对象 [shared [...]
为什么使用<!DOCTYPE HTML>
不管是刚接触前端,还是你已经“精通”web前端开发的内容,你应该知道在你写html的时候需要定义文档类型;你知道如果没有它,浏览器在渲染页面的时候会使用怪异模式;你知道各个浏览器在怪异模式下对各个元素渲染是有差异的。所以你会写像这样的doctype:
|
1 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
好在现在的各种web开发工具都足够强大,支持插入模板代码,因此你并不需要把这又长又臭的doctype一个个字母的敲出来。但是如果你受够了它,你也许可以尝试下面这个写法:
|
1 |
<!DOCTYPE html> |
哇哦,很简洁哦!好处显而易见:一、你可以轻松的写下这个doctype,而不用担心会写错;二、它是向后兼容的,是的,html5的doctype就是这样写的,并且现代浏览器都认识它。 如果你跟我一样一直以为:没有指定dtd将会开启浏览器的怪异模式,这种说法是错的!正确的说法应该是没有定义doctype才会开启怪异模式,也就是说你只需要定义<!doctype html>就可以让浏览器在严格模式(标准模式)下渲染页面,而不需要指定某个类型dtd。让我们来回顾一下,所有的浏览器都需要两种模式:怪异模式和严格模式(也有人叫标准模式)。IE 6 for Windows/mac, Mozilla, Safari和Opera 都实现了这两种模式,但是IE 6以下版本永远定在了怪异模式。关于两种模式,你需要知道以下几点: 在标准化之前写的页面是没有doctype的,因此没有doctype的页面是在怪异模式下渲染的。 反过来说,如果web开发人员加入的doctype,说明他知道他所要做的事情,大部分的doctype会开启严格模式(标准模式),页面也会按照标准来渲染。 任何新的或者未知的doctype都会开启严格模式(标准模式)。 每个浏览器都有自己的方式来激活怪异模式。你可以看看这个清单:http://hsivonen.iki.fi/doctype/ 注意:你可以根本不需要根据你选择的doctype来验证你的页面,只要doctype标签存在就足以开启严格模式(标准模式)了。如果你对我说的这些还是感到怀疑,那么请前往http://www.quirksmode.org/css/quirksmode.html#link2了解你想知道的内容。我们只需要一小段JavaScript代码就可以得到答案,它就是:
|
1 |
mode=document.compatMode; |
这个代码可以用来判断,当前浏览器是处于怪异模式还是标准模式,该属性的兼容性毋庸置疑,如果你表示怀疑,可以查看http://www.quirksmode.org/dom/w3c_html.html#t11。你可以在你想测试的浏览器里访问:http://wanz.im/demo/doctype-test.html,便可看到结果了,据我所知,这样并没有激活怪异模式,即使是ie6下,如果你有什么新发现,欢迎给我留言。
canvas JavaScript API学习(五)
写在前面 上篇文章我们了解了canvas用来处理图像的两个简单的方式:拉伸和裁切。这次我们来挑战像素级的图像处理,这话看起来挺唬人的,不过不用担心,它并没有那么可怕。 像素处理API 你可以通过ImageData对象在字节级的水平来处理图像数据,先看看与此相关的一些API属性及方法: imagedata = context . createImageData(sw, sh) 根据给定的尺寸返回一个ImageData对象,该尺寸为CSS像素值(CSS Pixel),返回的对象中的像素点都是黑色透明的,即rgba(0,0,0,0)。 imagedata = context . createImageData(imagedata) 返回一个跟参数所指对象大小一致的ImageData对象,返回的对象中的像素点都是黑色透明的。 imagedata = context . getImageData(sx, sy, sw, sh) 返回包含canvas指定区域图像数据的ImageData对象 imagedata . width imagedata . height 返回ImageData对象数据的实际尺寸,该值为设备像素值(Device Pixel)。 imagedata . data 返回一个一维数组,该数组包含按照RGBA顺序排列的范围从0到255的数据 context . putImageData(imagedata, dx, dy [, dirtyX, dirtyY, dirtyWidth, dirtyHeight ]) 将指定的ImageData对象的数据绘制到canvas上。 备注:globalAlpha,globalCompositeOperation,还有shadow属性在调用该方法时会被忽略。 createImageData()方法会根据所给的参数创建一个以sw为宽,sh为高的空白ImageData对象,当该方法只有imagedata 参数时,它将返回一个与参数所指的ImageData对象一样大小的ImageData对象,并且返回的ImageData对象是被填充为透明黑色的(transparent black)。 [...]