HTML5学习总结


html5 与 html4 区别

语法的改变

DOCTYPE 声明:&lt!DOCTYPE html&gt

指定字符编码:&ltmeta charset=”UTF-8”&gt,HTML5 开始推荐 UTF-8

所谓的字符是对各种文字和符号的总称,涵盖了各国文字、标点符号、图形符号和数字等。字符集是对多个字符的集合,常用的字符集有 ASCII、GB2312、Unicode、ISO 等。科学家为了让计算机准确处理各种字符集,需要对字符进行编码,以便计算机能够识别和存储各种文字。

在 HTML5 出现之前,浏览器会根据三种方式确认页面的编码方式,按优先级排列如下: 1)获取 HTTP 请求头中的 Content-Type 字符对于的值。 2)使用 meta 标签声明,语法格式如下:

3)外链资源使用 charset 属性声明编码格式,如在 script 标签中使用语法格式如下:
<script type="text/javascript" src="myscript.js" charset="UTF-8"></script>

HTML5 出现后,对字符集的使用做了大量的简化,可以使用以下语法进行字符声明:

<meta charset="utf-8">

对于日常网站开发,结合 HTML5 的字符集使用,建议: 1)最优先使用 HTTP 请求头指定编码。 2)统一全站字符集编码,HTML5 推荐使用 UTF-8 字符集。 3)使用 meta 标签确认字符集编码,尽可能放在 html 标签的第一个子元素位置 4)第三方引用的脚本,在不确认字符编码时,加上 charset 属性设置编码格式

为什么会产生乱码?
乱码产生的根本原因是你保存的编码格式和浏览器解析时的解码格式不匹配导致的。
乱码一般是英文以外的字符才会出现。

可以省略标记的元素: 1)不允许写结束标记的元素有:area、base、br、col、command、embed、hr、img、input、keygen、link、meta、param、source、track、wbr 2)可以省略结束标记的元素有:li、dt、dd、p、rt、rp、optgroup、option、colgroup、thead、tbody、bfoot、tr、td、th 3)可以省略全部标记的元素有:html、head、body、colgroup、tbody。

具有 boolean 值的属性:对于具有 boolean 之的属性,例如 disabled 与 readonly 等,当只写属性而不指定属性值时,表示属性值为 true,如果想要将属性值设为 false,可以不使用该属性值。

属性值可以省略引号

新增的元素和废除的元素

新增的元素:section、article、aside、header、hgroup、footer、nav、figure、vedio、audio、embed、mark、progress、time、ruby、rt、rp、wbr、canvas、command、details、datalist、datagrid、keygen、output、source、menu

新增的 input 类型:email、url、number、range、Date Pickers

废除的元素: 1)能用 css 替代的元素:basefont、big、center、font、s、strike、tt、u 2)不再使用 frame 框架,只支持 iframe 框架 3)只有部分浏览器支持的元素:applet、bgsound、blink、marquee 4)其他废除的元素:rb、acronym、dir、isindex、listing、xmp、nextid、plaintext

新增的属性和废除的属性

新增的属性: 1)表单相关的属性:autofocus、placeholder、form、required、autocomplete、min、max、multiple、pattern、step、formaction、formenctype、formmethod、formnovalidate、formtarget、novalidate 2)链接相关的属性:
为 a 与 area 元素增加了 media 属性
为 area 元素增加了 hreflang 和 rel 属性,主要目的是保持与 a 元素、link 元素的一致性
为 link 元素增加了新属性 sizes。该属性可以与 icon 元素结合使用(通过 rel 属性),该属性指定关联图标(icon 元素)的大小
为 base 元素增加了 target 属性,主要目的是保持与 a 元素的一致性
a 元素还有 download 属性 3)其他属性
为 ol 元素增加了 reversed 属性
为 meta 元素增加了 charset 属性
为 munu 元素增加了 type 与 label
为 style 元素增加了 scoped 属性
为 script 元素增加了 async 属性
为 html 元素增加了 manifest 属性
为 iframe 增加了 sandbox、seamless、srcdoc 属性

废除的属性:很多,略

全局属性

1)contentEditable
2)designMode: on 或 off
3)hidden 属性
4)spellcheck: 必须声明属性值为 true 或 false
5)tabindex

html5 结构

新增的主体结构元素

article 元素
article 元素代表文档、页面或应用程序中独立的、完整的可以被外部引用的内容。article 元素也可以用来表示插件,它的作用是使插件看起来好像内嵌在页面中一样。
section 元素
section 元素用于对网站或应用程序中页面上的内容进行分块。在 HTML5 中,article 元素可以看成是一种特殊种类的 section 元素,它比 section 元素更强调独立性。即 section 元素强调分段或分块,而 article 元素强调独立性。
section 元素使用禁忌:
1)不要将 section 元素用作设置样式的页面容器,那是 div 的工作;
2)如果 article 元素、aside 元素或 nav 元素更符合使用条件,不要使用 section 元素;
3)不要为没有标题的内容区块使用 section 元素。
nav 元素
nav 元素是一个可以用作页面导航的链接组
aside 元素
aside 元素用来表示当前页面或文章的附属信息部分。典型应用是侧边栏
time 元素和微格式
pubdate 属性

新增的非主体结构元素

header 元素
hgroup 元素
footer 元素
address 元素

表单与文件

新增元素和属性

新增属性
1)form 属性
当一个 input 元素被用于多个元素时,可以在 form 属性上将各表单 id 值以空格符分隔开来
2)formaction 属性
3)formmethod 属性
4)placeholder 属性
5)autofocus 属性
6)autocomplete 属性
autocomplete 属性规定输入字段是否应该启用自动完成功能。
自动完成允许浏览器预测对字段的输入。当用户在字段开始键入时,浏览器基于之前键入过的值,应该显示出在字段中填写的选项。
注释:autocomplete 属性适用于 form,以及下面的 input 类型:text,search,url,telephone,email,password,datepickers,range 以及 color。

大幅度增加和改良的 input 种类
1)url 类型
2)email 类型
3)date 类型
4)time 类型
5)datetime 类型
6)datetime-local 类型
7)month 类型
8)week 类型
9)number 类型
10)range 类型
11)search 类型
12)tel 类型
13)color 类型

output 元素的追加

表单验证

自动验证: required pattern min 和 max step
显示验证:checkValidity()方法
取消验证:
1)form 的 novalidate 属性
2)input 元素或 submit 元素的 formnovalidate 属性

HTML5 表单验证插件

html5Validate
自定义错误信息:setCustomValidity()方法

增强的页面元素

新增的 figure 元素和 figcaption 元素
新增的 details 元素和 summary 元素
input 和 datalist

<input type="text" list="province">
    <datalist id="province">
        <option value="北京"></option>
        <option value="上海"></option>
        <option value="浙江"></option>
    </datalist>

新增的 mark 元素:用来在搜索结果中高亮关键词,也常用来文章引用后加的标示,与 em()、strong 不同
新增的 progess 元素:表示任务的进度,如 Windows 系统中软件的安装、文件的复制等场景的进度。
新增的 meter 元素:表示某种计量,适用于温度、重量、金额等量化的表现。
新增的 menu 和 command 元素: menu 在 html4 被弃用,在 html5 中重定义,command 为 html5 新增,这两个标签目前基本没有浏览器支持
改良的 ol 列表:新增了 start 属性和 reversed 属性
改良的 dl 列表:html4 为定义列表(definition lists),html5 为描述列表(description list)
加以严格限制的 cite 元素:定义引用。可使用该标签对参考文献的引用进行定义,比如书籍或杂志的标题。不用来表示作者,除非标题是作者
重新定义的 small 元素:The small element represents side comments such as small print.而非通用展示性元素,通常用在诸如免责声明、注意事项、法律法规、版权声明等声明文字中,不应该应用在页面主体内容中

文件 API

FileList 对象和 file 对象:files 返回一个 FileList 对象
Blob 对象:Blob 对象有两个属性,size 属性表示一个 Blob 对象的字节长度,type 属性表示 MIME 类型,file 对象也继承了这个对象
FilReader 接口:FileReader 接口有 4 个方法,其中 3 个用来读取文件,一个用来中断读取。无论读取成功还是失败,方法不返回读取结果,结果保存在 result 属性中。
4 个接口方法:readAsDataURL、readAsBinaryString、readAsText、abort
FileReader 接口事件:onabort、onerror、onloadstart、onprogress、onload、onloadend
FileSystem
在使用 FileSystem 对象的相关应用接口时,首先要获得对沙箱文件系统的访问权限。
通过这个接口,可以进行文件的新建、修改、删除。
//获取兼容文件请求对象
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
//请求获取浏览器沙箱文件系统
//window.webkitStorageInfo.requestQuota is deprecated
navigator.webkitPersistentStorage.requestQuota(510241024,function(bytes){
window.requestFileSystem(window.PERSISTENT,bytes,function(file_system){
console.log(file_system);
},function(){});
},function(e){
console.log(‘Error’,e);
});
目前只有 chrome 支持,需启动本地服务。安装 chrome 扩展程序 HTML5 FileSystem Explorer 进行查看验证。

拖放 API

实现拖放的步骤
在 HTML5 中要实现拖放操作,至少要经过以下两个步骤: 1)将想要拖放的对象元素的 draggable 属性设为 true(draggable=”true”)。这样才能将元素进行拖放。另外 img 元素与 a 元素(必须指定 href)默认拖放。 2)编写与拖放有关的事件处理代码。拖放的几个事件:
dragstart:被拖放的元素
drag:被拖放的元素
dragenter:拖放过程中鼠标经过的元素
dragover:拖放过程中鼠标经过的元素
dragleave:拖放过程中鼠标经过的元素
drop:拖放的目标元素
dragend:拖放的目标元素

<h2>drag示例</h2>
<div id="dragme" draggable="true" style="width:200px;height:200px;border: 1px solid;">请拖放</div>
<div id="text" style="width:200px;height:200px;border: 1px solid;"></div>
<script type="text/javascript">
    function init(){
        //自定义图标
        var dragIcon = document.createElement('img');
        dragIcon.src = 'http://www.iconpng.com/png/miui-fruitsugar/twelvekeydialer.png';
        var source = document.getElementById('dragme');
        var dest = document.getElementById('text');
        //(1)拖放开始
        source.addEventListener('dragstart',function(e){
            //向dataTransfer对象追加数据
            var dt = e.dataTransfer;
            dt.effectAllowed = 'all';
            dt.setDragImage(dragIcon,-10,-10);
            dt.setData('text/plain','你好'); //setData一般采用两种两种数据格式,用于文本数据存储的"text/plain"和用于URL信息存储的"text/uri-list"
        },false);
        //(2)拖放事件
        dest.addEventListener('drop',function(e){
            var dt = e.dataTransfer;
            var text = dt.getData('text/plain');
            dest.textContent += text;
        },false);
        //(3)不执行默认处理(拒绝被拖放)
        dest.addEventListener('dragover',function(e){
            e.preventDefault(); //必须,阻止默认行为
        },false);
    }
    init();
</script>

处理浏览器兼容性与 Modernizr 库

处理浏览器兼容性

一般较为常见的安全检测手段有 4 种: 1)检测全局对象,如 window、navigator 是否拥有指定的属性,如离线存储、地址位置信息等 2)通过创建新元素,检查元素对象上是否拥有指定的属性,如 Canvas 等。 3)通过创建新元素,检查元素对象上是否拥有指定的方法,同时调用该方法,并判断返回值,如检查 video 元素支持的视频格式 4)通过创建新元素,设置元素对象上的指定属性值,并判断设定后的值是否被保留。

Modernizr 库概述

随着 HTML5 和 CSS3 加入越来越多的模块,检查各种浏览器是否支持这些模块,成了一大难题。Modernizr 就是用来解决这个问题的一个 JavaScript 库。
首先,从 modernizr.com 下载这个库。下载的时候,可以选择所需要的模块。然后,将它插入 HTML 页面的头部,放在 head 标签之中。

<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
  <meta charset="utf-8">
  <script src="js/modernizr.js"></script>
</head>
</html>

Modernizr 库 CSS 的新增 class

使用 Modernizr 以后,首先会把 html 元素的 class 替换掉。以 chrome 浏览器为例,新增的 class 大概是下面的样子。

<html class="js no-touch postmessage history multiplebgs boxshadow opacity cssanimations csscolumns cssgradients csstransforms csstransitions fontface localstorage sessionstorage svg inlinesvg blobbuilder blob bloburls download formdata">

IE 7 则是这样:

<html class="js no-touch postmessage no-history no-multiplebgs no-boxshadow no-opacity no-cssanimations no-csscolumns no-cssgradients no-csstransforms no-csstransitions fontface localstorage sessionstorage no-svg no-inlinesvg wf-loading no-blobbuilder no-blob no-bloburls no-download no-formdata">

然后,就可以针对不同的 CSS class,指定不同的样式。

.button {
   background: #000;
   opacity: 0.75;
}

.no-opacity .button {
   background: #444;
}

Modernizr 库 JavaScript 侦测

除了提供新增的 CSS class,Modernizr 还提供 JavaScript 方法,用来侦测浏览器是否支持某个功能。

Modernizr.cssgradients; //True in Chrome, False in IE7

Modernizr.fontface; //True in Chrome, True in IE7

Modernizr.geolocation; //True in Chrome, False in IE7

if (Modernizr.canvas){
    // 支持canvas
} else {
   // 不支持canvas
}

if (Modernizr.touch){
    // 支持触摸屏
} else {
   // 不支持触摸屏
}

Modernizr 库加载器

Modernizr 允许根据 Javascript 侦测的不同结果,加载不同的脚本文件。

Modernizr.load({
  test :        Modernizr.localstorage,
  yep  :        'localStorage.js',
  nope :        'alt-storageSystem.js',
  complete :    function () { enableStorgeSaveUI();}
});

Modernizr.load 方法用来加载脚本。它的属性如下:
test:用来测试浏览器是否支持某个属性。
yep:如果浏览器支持该属性,加载的脚本。
nope:如果浏览器不支持该属性,加载的脚本。
complete:加载完成后,运行的 JavaScript 代码。
可以指定在支持某个功能的情况,所要加载的 JavaScript 脚本和 CSS 样式。

Modernizr.load({
  test : Modernizr.touch,
  yep :  ['js/touch.js', 'css/touchStyles.css']
});

本章 Modernizr 部分来自阮一峰的 JavaScript 标准参考教程的Modernizr

绘制图形

canvas 元素的基础知识

canvas:画布
检测 Canvas 强化版:

function isSupportCanvas(){
    var cvs = document.createElement('canvas');
    // 首先判断getContext方法是否存在
    if(!cvs.getContext){
        return false;
    }
    // 判断是否含有fillText方法
    return typeof cvs.getContext('2d').fillText == 'function';
}

绘制矩形
用 canvas 绘制图形时,需要经过几道步骤: 1)取得 canvas 元素 2)取得上下文(context):getContent 方法 3)设定绘图样式(style):fillStyle、strokeStyle 4)指定线宽:lineWidth
5)context.fillRect(x,y,width,height)
context.strokeRect(x,y,width,height)
context.clearRect(x,y,width,height)
填充(fill)和绘制边框(stroke)

使用路径

绘制圆形
开始创建路径:beginPath 方法
创建图形的路径:context.arc(x,y,radius,startAngle,endAngle,anticlockwise)
路径创建完成后关闭路径: closePath 方法
设定绘制样式,调用绘制方法,绘制路径。

如果路径没有关闭:已经创建的路径会永远保留着,即使绘制完毕后,因此会进行重叠绘制,因此要对路径进行管理

moveTo(x,y)和 lineTo(x,y)

使用 bezierCurveTo 绘制曲线:context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y);
二次样条曲线:context.quadraticCurveTo(in float cpx,in float cpy,in float x,in float y);

绘制渐变图形

绘制线性渐变:context.createLinearGradient(xStart,ySTart,xEnd,yEnd)
设定渐变颜色:context.addColorStop(offset,color),渐变起点 offset 为 0,渐变结束点为 1。然后将 style 设定为 LinearGradient 对象。
绘制径向渐变:context.createRadialGradient(xStart,yStart,radiusStart,xEnd,yEnd,radiusEnd);

绘制变形图形

坐标变换

  1. 平移:context.translate(x,y);
  2. 缩放:context.scale(x,y);
  3. 旋转:context.rotate(angle);
    坐标变换与路径的结合使用:另外写一个创建路径的函数,然后在坐标变换的同时调用该函数

矩阵变换
context.transform(a,b,c,d,e,f);
这个方法与 css3 matrix 方法差不多 1)矩阵与 translate(x,y):(1,0,0,1,x,y) 2)矩阵与 scale(x,y):(x,0,0,y,0,0) 3)矩阵与 rotate(angle):(Math.cos(angle _ Math.PI / 180),Math.sin(angle _ Math.PI / 180),-Math.cos(angle _ Math.PI / 180),Math.sin(angle _ Math.PI / 180),0,0) 4)矩阵与 skew(anglex,angley):(1,Math.tan(angley _ Math.PI / 180),Math.tan(anglex _ Math.PI / 180),1,0,0)(css3 非 context 方法)

矩阵是一种高级应用,可以做一些没有提供的效果,比如镜像对称效果:((1-kk) / (1+kk), 2k / (1 + kk), 2k / (1 + kk), (kk - 1) / (1+kk), 0, 0)

可以用 setTransform(a,b,c,d,e,f)方法来重置变换矩阵

图形组合

context.globalCompositeOperation = type;
type 值:”source-over”,”destination-over”,”source-in”,”destination-in”,”souce-out”,”destination-out”,”source-atop”,”destination-atop”,”lighter”,”copy”,”xor”

给图形绘制阴影

shadowOffsetX(),shadowOffsetY(),shadowColor(),shadowBlur()。如果想要后面的图形不再有阴影,只要把 shadowColor 设定为 rgba(0,0,0,0)就可以了。

使用图像

绘制图像

context.drawImage(image,x,y)
context.drawImage(image,x,y,w,h)
context.drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh)
var image = new Image();
image.src = "img/17.jpg";
image.onload = function(){};

图像平铺
一是使用 drawImage 方法循环处理,二是使用 context.createPattern(image,type);
type: no-repeat,repeat-x,repeat-y,repeat
使用 createPattern 方法创建填充样式,然后将该样式指定给图形上下文对象的 fillStyle 属性,最后再填充画布。

图像裁剪
使用图形上下文不带参数的 clip 方法来实现 canvas 元素的图像裁剪功能。该方法使用路径来对 canvas 画布设置一个裁剪区域。因此先创建路径,设置裁剪区域,再绘制图像。
如何取消裁剪区域:使用绘制状态的保存和恢复功能。save 方法和 restore 方法。

像素处理
反显:

var imagedata;
var i;
var n = imagedata.data.length;
context.drawImage(image,0,0);
imagedata = context.getImageData(0,0,image.width,image.height);
for( i = 0; i < n; i += 4){
    imagedata.data[i] = 255 - imagedata.data[i];
    imagedata.data[i+1] = 255 - imagedata.data[i+1];
    imagedata.data[i+2] = 255 - imagedata.data[i+2];
}
context.putImageData(imagedata,0,0);

绘制文字

fillText(text,x,y,[maxWidth]);
strokeText(text,x,y,[maxWidth]);
font 属性、fontAlign 属性、fontBaseline 属性
context.measureText(text);

补充知识

保存与恢复状态
图形上下文对象的当前状态的保存与恢复可以应用在以下场合: 1)图像或图形变形 2)图像裁剪 3)改变图形上下文以下属性时:
fillStyle
font
globalAlpha
globalCompositionOperation
lineCap
lineJoin
lineWidth
miterLimit
shadowBlur
shadowColor
shadowOffsetX
shadowOffsetY
strokeStyle
textAlign
textBaseline
clipping 区域
转换矩阵等
最后保存的最先还原

保存文件
canvas API 保存文件的原理实际上是把当前的绘画状态输出到一个 data URL 地址所指向的数据中的过程。
canvas.toDataURL(type);
type 表示输出数据的 MIME 类型

简单动画的制作 1)预先编写好用来绘图的函数,在改函数中先用 clearRect 方法将画布整体或局部擦除 2)使用 setInterval 方法设置动画的间隔时间

canvas 动画学习参考: 1.HTML5-Canvas 动画原理 2.Canvas 最佳实践(性能篇)

其他相关

SVG
SVG 是 Scalable Vecotor Graphics 的缩写,即可缩放矢量图形,是基于 XML(可扩展标记语言)用来描述二维矢量图形的一种图形格式。
SVG 有如下优点: 1.基于 XML,继承了 XML 的扩平台和可扩展的特性 2.采用文本描述图形对象,利用搜索引擎通过文本内容搜索图片信息 3.良好的交互和动态特性,可以在其中嵌入动画,通过脚本收缩、旋转调整图形 4.对 DOM 支持完整,可以通过脚本获取元素,监听元素事件 5.体积小下载快,在互联网上传输有明显优势
WebGL

媒体播放

<video id="player" width="600" height="450" controls preload>您的浏览器不支持HTML5
    <source src="./videos/echo-hereweare.mp4"></source>  <!-- 提供默认的播放视频  -->
</video>

1)video 播放相关 API

只读属性:
video.duration:整个媒体文件的播放时长,单位 s
video.paused :如果媒体文件被暂停,则返回 true;如果还没开始播放,默认返回 true
video.ended :如果媒体文件播放完毕,则返回 true

可写属性:
video.currentTime:以 s 为单位返回从开始播放到现在所用的时间。在播放过程中,设置 currentTime 来进行搜索,并定位到媒体文件的特定位置
video.volume :在 0.0 到 1.0 之间设置音频音量的相对值,或者查询当前音量相对值
video.muted :检测当前是否为静音,是则为 true;为文件设置静音或消除静音

控制函数:
video.play() :播放视频文件
video.pause() :暂停处于播放状态的视频文件
video.canPlayType() :测试 video 元素是否支持给定 MIME 类型的文件

监听事件:
ontimeupdate :当 video.currentTime 发生改变时触发该事件

2)全屏控制 API
说明:这里只给出 webkit 的全屏 API,本代码没有做兼容性处理,主要应用了 webkit 的一些高级 API 和 chrome 的伪元素,所以前面请大家用 chrome 打开演示地址。

video.webkitRequestFullScreen():全屏显示
document.webkitCancelFullScreen():退出全屏
document.webkitIsFullScreen:如果当前处于全屏状态,则返回 true,否则返回 false
document.addEventListener(‘webkitfullscreenchange’, handler):当在全屏和非全屏状态切换时,触发该事件

3)本地文件读取 API
说明:我的这个视频播放器支持从本地添加视频文件播放,支持的格式在 webkit 浏览器支持的 html5 视频播放标准范围内。本地文件读取 API 是 html5 的新标准。

window.URL.createObjectURL(file):file 为文件对象,该函数返回指向文件的对象 URL,通过该 URL 可以访问文件。

video.src = window.URL.createObjectURL(file);

音视频的实时通信:WebRTC 技术,该技术主要用于支持浏览器进行实时的语音对话和视频通信。

视频播放学习参考: 1.打造自己的 html5 视频播放器 2.视频播放的那些事

本地存储

Web Storage

cookie 会带来什么问题:
1)cookie 大小限制在 4k 左右,不适合存业务数据
2)cookie 每次随 HTTP 事务一起发送,浪费带宽
localstorage 可以说是对 cookie 的优化,使用它可以方便在客户端存储数据,并且不会随着 HTTP 传输,但也不是没有问题:

1)localstorage 大小限制在 5m 左右,各个浏览器不一致
2)localstorage 在隐私模式下不可读取
3)localstorage 本质是在读写文件,数据多的话会比较卡(firefox 会一次性将数据导入内存,想想就觉得吓人啊)
4)localstorage 不能被爬虫爬取,不要用它完全取代 URL 传参

sessionStorage:
保存数据:sessionStorage.setItem(key,value);
读取数据:sessionStorege.getItem(key);
localStorage:
保存数据:localStorage.setItem(key,value);
读取数据:localStorege.getItem(key);
localStorage.length
localStorage.key(index)
localStorage.clear()

本地数据库

SQLLite

要使用 SQLLite 数据库,有两个必要的步骤: 1)创建访问数据库的对象 2)使用事务处理
var db = openDatabase(‘mydb’,’1.0’,’Test DB’,2 * 1024 *1024);
db.transaction(function(tx){
tx.executeSql(‘CREATE TABLE IF EXISTS LOGS (id unique Log)’);
});
transaction 方法中的处理 1)追加数据
tx.executeSql(‘INSERT INFO MsgData VALUES(?,?,?)’,[name,message,time],function(tx,rs){},function(tx,error)); 2)创建数据表
tx.executeSql(‘CREATE TABLE IF NOT EXISTS MsgData(name TEXT,message TEXT,tiem INTEGER)’,[]); 3)获取全部数据
tx.ececuteSql(‘SELECT * FROM MsgData’,[],…);

indexedDB

indexedDb 是 HTML5 推出的一种轻量级的 NoSQL 数据库,即常说的非关系型数据库。比起传统的关系型数据库,NoSQL 数据库具有易扩展、读写快速、成本低廉等特点。HTML5 的 IndexedDB 还包含了常见的数据库构造,如事务、索引、游标等,在 API 的使用上分为同步和异步两种形态。
// 创建一个数据库
var request = indexedDB.open(‘Html5IndexedDB’,2);
request.onerror = function(e){
console.log(e);
};
//监听事务事件
request.onupgradeneeded = function(e){
// 获取数据库对象
var db = e.target.result;
// 创建对象存储空间存放用户信息
objectStore = db.createObjectStore(‘users’,{keyPath:”html5”});
// 创建索引来通过 name 搜索客户
objectStore.createIndex(‘name’,’name’,{unique:false});
objectStore.createIndex(‘id’,’id’,{unique:true});
objectStore.add({html5:’1’,name:’小王’,sex:’女’,id:’3323’,age:23});
}

离线应用程序

离线 Web 应用程序是指:当客户端本地与 Web 应用程序的服务器没有建立连接时,也能正常在客户端使用该 Web 应用程序进行有关操作。

本地缓存和浏览器缓存的区别:

1)本地缓存为整个 web 应用程序服务的,而浏览器的网页缓存只服务于单个网页。任何网页都具有网页缓存。而本地缓存至缓存那些指定的缓存的页面。

2)网页缓存不安全不可靠,因为我们不知道在网站中到底缓存了哪些网页,以及缓存了网页上的哪些资源。而本地缓存可靠,我们可以控制对哪些内容进行缓存,不对哪些内容进行缓存,开发人员还可以利用编程的手段来控制缓存的更新,利用缓存对象的各种属性、状态和事件来开发出更加强大的离线应用程序。

3)(有些)浏览器会主动保存自己的缓存文件以加快网站加载速度。但是要实现浏览器缓存必须要满足一个前提,那就是网络必须要保持连接。如果网络没有连接,即使浏览器启用了对一个站点的缓存,依然无法打开这个站点。只会收到一条错误信息。而使用离线 web 应用,我们可以主动告诉浏览器应该从网站服务器中获取或缓存哪些文件,并且在网络离线状态下依然能够访问这个网站。

实现 HTML5 应用程序缓存

实现 HTML5 应用程序缓存非常简单,只需三步,并且不需要任何 API。只需要告诉浏览器需要离线缓存的文件,并对服务器和网页做一些简单的设置即可实现。 1)创建一个 cache.manifest 文件,并确保文件具有正确的内容。 2)在服务器上设置内容类型。 3)所有的 HTML 文件都指向 cache.manifest。

具体实现:
首先我们建立一个名为 cache.manifest 的文件,Windows 平台下用记事本即可(也可用其他的 IDE)。文件内容如下:

CACHE MANIFEST
#version1
CACHE:
index.html
404.html
favicon.ico
robots.txt
humans.txt
apple-touch-icon.png
css/normalize.min.css
css/main.css
css/bootmetro-icons.min.css
img/pho-cat.jpg
img/pho-huangshan.jpg

FALLBACK:
online.js local.js

NETWORK:
*

注意事项: 1)第一行必须是”CACHE DMANIFEST”文字,以把本文件的作用告知浏览器,即对本地缓存中的资源文件进行具体设置。 2)在 manifest 文件中,可以加上注释来进行一些必要说明或解释。注释行以”#”文字开头。 3)在 CACHE 之后的部分为列出我们需要缓存的文件。 4)在 FALLBACK 之后的部分每一行中指定两个资源文件,第一个资源文件为能够在线访问时使用的资源文件,第二个资源文件为不能在线访问时使用的备用资源文件。 5)在 NETWORK 之后可以指定在线白名单,即列出我们不希望离线存储的文件,因为通常它们的内容需要互联网访问才有意义。另外,在此部分我们可以使用快捷方式:通配符*。这将告诉浏览器,应用服务器中获取没有在显示部分中提到的任何文件或 URL。

服务器上设置内容类型。
真正运行或测试离线 web 应用程序的时候,需要对服务器进行配置,让服务器支持 text/cache-manifest 这个 MIME 类型(在 h5 中规定 manifest 文件的 MIME 类型是 text/cache-manifest)。例如对 Apache 服务器进行配置的时候,需要找到{apache_home}/conf/mime.type 这个文件(.htaccess),并在文件最后添加如下所示代码:

text/cache-manifest .manifest

在微软的 IIS 服务器中的步骤如下所示:
(1).右键选择默认网站或需要添加类型的网站,弹出属性对话框
(2).选择”http 头”标签
(3).在 MIME 映射下,单击文件类型按钮
(4).在打开的 MIME 类型对话框中单击新建按钮
(5).在关联扩展名文本中输入”manifest”,在内容类型文本框中输入”text/cache-manifest”,然后点击确定按钮。

设置 HTML 文件的指向。
完成这一步后,就完成了 web 离线缓存的所有步骤。由于浏览的文件内容都没有更改且存储在本地,因此现在网页的打开速度会更快(即使是在线状态也如此)。

注意事项: 1)网站的每一个 html 页面都必须设置 html 元素的 manifest 属性。 2)在你的整个网站应用中,只能有一个 cache.manifest 文件(建议放在网站根目录下); 3)部分浏览器(如 IE8-)不支持 HTML5 离线缓存;
4)“#” 开头的注释行可满足其他用途。应用的缓存会在其 manifest 文件更改时被更新。如果您编辑了一幅图片,或者修改了一个 JavaScript 函数,这些改变都不会被重新缓存。更新注释行中的日期和版本号是一种使浏览器重新缓存文件的办法。

applicationCache 的两个方法

applicationCache 的 update 方法
显式调用了更新缓存算法以检测是否有最新版本的的应用程序。这导致浏览器检测同一个清单文件(并触发相同的事件),这和第一次载入应用程序时的效果是一样的。
applicationCache 的 swapCache 方法:
它告诉浏览器可以弃用老缓存,所有的请求都从新缓存中获取。注意,这并不会重新载入应用程序:所有已经载入的 html 文件、图片、脚本等资源都不会改变。但是,之后的请求将从最新的缓存中获取。这会导致“版本错乱”的问题,因此一般不推荐使用,除非应用程序设计得很好,确保这样的方式没有问题。只有 ApplicationCache.UPDATEREADY 和 ApplicationCache.ABSOLETE 时调用 swapCache()才有意义(当状态 OBSOLETE 时,调用它可以立即弃用废弃的缓存,让之后所有的请求都通过网络获取)。如果状态属性是其他数值的时候调用 swapCache()方法,它就会抛出异常。

function init(){
    setInterval(function(){
        //手工检查是否更新
        applicationCache.update();
    },5000);
    applicationCache.addEventListener('updateready',function(){
        if( confirm("本地缓存已被更新,需要刷新页面来获取应用程序最新版本,是否刷新?") ){
            // 手工更新本地缓存
            applicationCache.swapCache();
            // 重置画面
            location.reload();
        }
    },true);
}
init();

applicationCache 对象的事件

1.checking 事件
2.downloading 事件
3.progress 事件
4.cached 事件
5.noupdate 事件
6.updateready 事件
7.obsolete 事件
8.error 事件

(1).没有可用更新
如果应用程序已经缓存并且清单文件没有动,则浏览器会触发 noupdate 事件
(2).有可用更新
如果应用程序已经缓存并且清单元件有改动,则浏览器会触发 downloading 事件并开始下载和缓存清单文件中列举的所有资源。随着下载过程的进行浏览器还会触发”progress”事件,在下载完成后,会触发”updateready”事件。
(3).首次载入新的应用程序
如果还未缓存应用程序,如上所述 downloading,progress 事件都会触发。但是,当下载完成后,浏览器会触发”cached”事件而不是 updateready 事件
(4).浏览器处于离线状态
如果浏览器处于离线状态,它无法检查清单文件,同时它会触发“error”事件。如果一个未缓存的应用程序引用了不存的清单文件,浏览器也会触发该事件
(5).清单文件不存在
如果浏览器处理在线状态,应用程序也已经缓存起来,但是清单文件不存在,浏览器会触发 obsolete 事件,并将该应用程序从缓存中移除。

如何判断在线还是离线状态?

navigator.onLine 是 HTML5 定义用来检测设备是在线还是离线。对应的值为 false 或 true。
HTML5 定义了 online 和 offline 事件用于监听网络状态变化。

window.addEventListener('online', callback); // 离线到上线
window.addEventListener('offline', callback); // 上线到离线

通信 API

跨文档消息传输

跨文档消息传递(Cross Document Messaging),有时候简称 XDM。指的是来自不同域的页面间传递消息。比如:abc.com 与内联框架中的 efg.com 进行通信。

XDM 的核心是 postMessage()方法,这是 HTML5 规范的 api,意思就是向另一个地方发送消息,除了 XDM 中有 postMessage()方法,在 HTML5 规范中,其他地方也有相同的方法名,比如 web worker 中、WebSockets 以及 Server-SentEvents 中。但目的都是向另一个地方发送数据,只不过在 XDM 中,另一个地方指的是页面中的 iframe 框架,或者由当前页面弹出的窗口。

postMessage()方法

postMessage()方法接收两个参数:postMessage(message, targetOrigin):

message:传递的消息,可以是任意的数据类型,不过为了保证兼容性,最好只传递字符串(部分浏览器智能处理字符串),对于对象的数据,可以先用 JSON.stingify()方法转成字符串,然后再通过 JSON.parse()方法转成对象。在低版本的浏览器中,可以使用 json2.js 实现相同的效果。
targetOrigin:消息接收方的域(URL 地址)。postMessage 会将 message 发送到该窗口,如果不指定目标源,可以设置成*,表示消息发送到任意窗口。第二个参数对保障安全通信非常重要,可以防止浏览器把消息传递到不安全的地方。

postMessage()方法实践

本地建立一个 html 文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>postMessage</title>
</head>
<body>
<input type="text" id="message"><button>发送消息</button>
<iframe src="http://localhost:63342/post%20text/iframe.html" id="iframe1"></iframe>
<script>
    window.onload = function(){
        var message = document.getElementById("message"),
                btn = document.getElementsByTagName("button")[0],
                iframe = document.getElementById("iframe1");

        var iWin = iframe.contentWindow;

        btn.onclick = function(){
            iWin.postMessage(message.value,"http://localhost:63342/post%20text/test.html");
        }
    }
</script>
</body>
</html>

iframe 页面

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <script>
        window.onmessage = function(e){
            console.log(e);
            document.body.innerHTML = "";
            document.body.innerHTML = e.data;
        }
    </script>
</body>
</html>

这样,当我在文本框中输入内容并且点击发送的时候,框架就可以获取到我发送的信息,从而可以进行相应的操作。

onmessage 事件
当接收到 XDM 消息时,触发 window 对象的 onmessage 事件,这个事件是以异步形式触发的。onmessage 事件有三个重要的参数:data,origin,source。

data:postMessage 传递进来的值
origin:发送消息的文档所在的域
source:发送消息文档的 window 对象的代理,如果是来自同一个域,则该对象就是 window,可以使用其所有方法,如果是不同的域,则该 window 是不能使用的,除了调用 postMessage()方法之外。
接收到消息后,验证消息的来源是很重要的,就像给 postMessage()方法指定第二个参数,以确保浏览器不会把消息发送给其他框架一样。判断其 origin 即可判断来源:

//iframe页面
window.onmessage = function(e){
    if(e.origin === 'http://sandbox.runjs.cn'){
        //处理数据
        //接收相应
        e.source.postMessage("已经收到信息!", "http://localhost:63342/post%20text/test.html"");
    }
}

浏览器兼容性
就像 localStorage 一样,IE8 也支持。

总结

postMessage 方法进行跨文档信息传递简单方便
在不同域时,event.source 中的 window 对象为代理 window 对象,只能调用 postMessage()方法
onmessage 事件是 window 对象上得事件,在使用时注意 IE 的事件处理程序,attachEvent

原文:操作 iframe–postMessage 跨文档消息传递

XMLHttpRequest Level 2

XMLHttpRequest Level 2 是早期 XMLHttpRquest 的升级版,最初的 XMLHttpRquest 被设计为仅限于同源通信,不能跨域进行数据传输,导致后续演变出 JSONP 方法。XMLHttpRquest Level 2 对同源策略进行了修改,允许跨域的数据请求,同时还添加了 progress 事件用于监听请求进度,返回进度信息。XMLHttpRquest Level 2 要求所有跨域的请求都要使用 HTTP 协议中的 origin 信息头,同时数据接收服务器需要具备 CORS 策略,各种服务器的 CORS 策略设置可以参考网站http://enable-cors.org/
兼容性:IE10+
客户端:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body></body>
</html>

数据:

<input type="text" /><button>获取</button>

<script type="text/javascript">
  document.querySelector('button').addEventListener(
    'click',
    function (e) {
      e.preventDefault();
      var xhr = new XMLHttpRequest();
      if (typeof xhr.withCredentials == undefined) {
        console.log('浏览器不支持 html5 XMLHttpRequst Level 2 的跨域请求支持');
      } else {
        xhr.onload = function () {
          var data = JSON.parse(xhr.responseText);
          document.querySelector('input').value = data.data;
        };
        xhr.onerror = function (e) {
          console.log(e);
        };
        xhr.open('GET', 'http://localhost:8080', true);
        xhr.send();
      }
    },
    false
  );
</script>

服务端(nodejs):

var http = require('http');
http
  .createServer(function (req, res) {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:63342');
    res.setHeader('Access-Control-Allow-Methods', 'GET', 'POST');
    req.setEncoding('utf-8');
    res.end(JSON.stringify({ data: 'Hello World!' }));
  })
  .listen(8080, function () {
    console.log('listing on http://localhost:8080');
  });

XMLHttpRequest Level 2 对远端请求的服务器有一定的要求,需要在服务器端返回的 HTTP 信息头中指明支持的域名。如果想对所有请求都通过处理,可以设置为”*“号。如果要指定多个,一般会认为使用以下写法:

res.setHeader('Access-Control-Allow-Origin','http://localhost,http://test.com'); //域名之间使用逗号
res.setHeader('Access-Control-Allow-Origin','http://localhost http://test.com'); //域名之间使用空格

非常不幸的是,浏览器无法识别这两种返回头,推荐先对请求域名做判断,如果符合业务要求,再设置对于域名的 Access-Control-Allow-Origin 头信息。

Web Socket 通信

在讲 Websocket 之前,先讲讲 long poll 和 ajax 轮询的原理。
首先是 ajax 轮询,ajax 轮询的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。
long poll 其实原理跟 ajax 轮询差不多,都是采用轮询的方式,不过采取的是阻塞模型(一直打电话,没收到就不挂电话),也就是说,客户端发起连接后,如果没消息,就一直不返回 Response 给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。
从上面可以看出其实这两种方式,都是在不断地建立 HTTP 连接,然后等待服务端处理,可以体现 HTTP 协议的另外一个特点,被动性。
何为被动性呢,其实就是,服务端不能主动联系客户端,只能有客户端发起。
通过上面这个例子,我们可以看出,这两种方式都不是最好的方式,需要很多资源。
一种需要更快的速度,一种需要更多的’电话’。这两种都会导致’电话’的需求越来越高。
哦对了,忘记说了 HTTP 还是一个无状态协议。

所以在这种情况下出现了,Websocket 出现了。
他解决了 HTTP 的这几个难题。
首先,被动性,当服务器完成协议升级后(HTTP->Websocket),服务端就可以主动推送信息给客户端啦。
就变成了这样,只需要经过一次 HTTP 请求,就可以做到源源不断的信息传送了。(在程序设计中,这种设计叫做回调,即:你有信息了再来通知我,而不是我傻乎乎的每次跑来问你)
这样的协议解决了上面同步有延迟,而且还非常消耗资源的这种情况。
同时,在传统的方式上,要不断的建立,关闭 HTTP 协议,由于 HTTP 是非状态性的,每次都要重新传输 identity info(鉴别信息),来告诉服务端你是谁。
同时由客户主动询问,转换为服务器(推送)有信息的时候就发送(当然客户端还是等主动发送信息过来的。。),没有信息的时候就交给接线员(Nginx),不需要占用本身速度就慢的客服(Handler)了
知乎参考
进一步学习

Socket.IO 通信框架

Socket.IO 是 Guillermo Rauch 开发的基于 Node.js 的应用项目,以实现跨浏览器和跨平台应用为目标。Socket.IO 针对不同的浏览器会做自动优雅降级,选择当前浏览器最合适的实现方式,如在一些不支持 HTML5 WebSocket 的浏览器上,会使用长连接的 Ajax 技术。同时 Socket.IO 提供了一套平台统一的应用程序接口,开发者在使用时完全不用考虑浏览器的兼容问题。

Web Workers

JavaScript 语言采用的是单线程模型,也就是说,所有任务排成一个队列,一次只能做一件事。随着电脑计算能力的增强,尤其是多核 CPU 的出现,这一点带来很大的不便,无法充分发挥 JavaScript 的潜力。

Web Worker 的目的,就是为 JavaScript 创造多线程环境,允许主线程将一些任务分配给子线程。在主线程运行的同时,子线程在后台运行,两者互不干扰。等到子线程完成计算任务,再把结果返回给主线程。因此,每一个子线程就好像一个“工人”(worker),默默地完成自己的工作。这样做的好处是,一些高计算量或高延迟的工作,被 worker 线程负担了,所以主进程(通常是 UI 进程)就会很流畅,不会被阻塞或拖慢。
在现实开发中 Web Worker 常常被用于处理大型密集型数据任务,可以有效的避免阻塞主 UI 线程渲染交互。

Worker 线程分成好几种。 1)普通的 Worker:只能与创造它们的主进程通信。
2)Shared Worker:能被所有同源的进程获取(比如来自不同的浏览器窗口、iframe 窗口和其他 Shared worker),它们必须通过一个端口通信。
3)ServiceWorker:实际上是一个在网络应用与浏览器或网络层之间的代理层。它可以拦截网络请求,使得离线访问成为可能。

Web Worker 有以下几个特点: 1)同域限制。子线程加载的脚本文件,必须与主线程的脚本文件在同一个域。
2)DOM 限制。子线程所在的全局对象,与主进程不一样,它无法读取网页的 DOM 对象,即 document、window、parent 这些对象,子线程都无法得到。(但是,navigator 对象和 location 对象可以获得。) 3)脚本限制。子线程无法读取网页的全局变量和函数,也不能执行 alert 和 confirm 方法,不过可以执行 setInterval 和 setTimeout,以及使用 XMLHttpRequest 对象发出 AJAX 请求。 4)文件限制。子线程无法读取本地文件,即子线程无法打开本机的文件系统(file://),它所加载的脚本,必须来自网络。

注意线程嵌套在 chrome 中有 bug

线程中可用的变量、函数与类:
self:self 关键词用来表示本线程范围内的作用域
postMessage(message):向创建线程的源窗口发送信息
worker.postMessage():向子线程中提交信息
onmessage:获取接收信息的事件句柄
importScripts(urls):导入其他 JavaScript 脚本文件 importScript(‘script1.js’,’scripts\script2.js’,’scripts\script3.js’);
navigator 对象
sessionStorage、localStorage
XMLHttpRequest
Web Workers
setTimeout()/setInterval()
close:可用结束本线程
eval()、isNaN()、escape()等,可以使用所有 JavaScript 核心函数
object:可以创建和使用本地对象
WebSockets:可以使用 WebSockets API 来向服务器发送和接收信息

获取地理位置

有哪些定位数据

1.IP 地址
2.GPS(Global Positioning System)
3.RFID(Radio Frequency IDentification,即射频识别)
4.Wi-Fi 地址
5.GSM 或 CDMA 手机的 ID 6.用户自定义的地理位置数据

Geolocation API 的基本知识

获取当前的地理位置

navigator.geolocation.getCurrentPosition(success,error,options);

第一个参数为获取当前地理位置成功时所执行的回调函数,第二个参数为获取失败时所执行的回调函数,第三个参数为一些可选属性的列表。
若成功,则 getCurrentPosition()方法返回对象。始终会返回 latitude、longitude 以及 accuracy 属性。如果可用,则会返回其他下面的属性。
coords.latitude 十进制数的纬度
coords.longitude 十进制数的经度
coords.accuracy 位置精度
coords.altitude 海拔,海平面以上以米计
coords.altitudeAccuracy 位置的海拔精度
coords.heading 方向,从正北开始以度计
coords.speed 速度,以米/每秒计
timestamp 响应的日期/时间
获取当前地理位置失败
该回调函数使用一个 error 对象作为参数,这个参数具有以下两个属性:
code 属性:
用户拒绝了位置服务(属性值为 1)
获取不到位置信息(属性值为 2)
获取信息超时错误(属性值为 3)
message 属性
message 属性为一个字符串,在该字符串中包含了错误信息

getCurrentPosition 方法中的第三个参数可以省略,它是一些可先属性的列表:
enableHighAccuracy:是否要求高精度的地理位置信息。在很多设备上设置了都没用,多数情况下把该属性设为默认。
timeout:超时设置
maximumAge:对地理位置信息进行缓存的有效时间。

持续监视当前地理位置信息

watchCurrentPosition(onSuccess,onError,options);

停止获取用户的当前地理位置信息
clearWatch(watchId)
使用方法和 clearTimeout 差不多

微数据

HTML5 微数据规范是一种标记内容以描述特定类型的信息,例如评论、人物信息或事件。每种信息都描述特定类型的项,例如人物、事件或评论。例如,事件可以包含 venue、starting time、name 和 category 属性。
微数据使用 HTML 标记(常为 span 或 div)中的简单属性为项和属性指定简要的描述性名称。
HTML5 扩展之微数据与丰富网页摘要

History API

HTML5 中给 History 新增了两个方法,允许开发者逐条地添加和修改历史记录,方法如下:
pushState:在历史堆栈的顶部添加一条记录,history.pushState({}, “页面标题”, “xxx.html”);
replaceState:更改当前页面的历史记录,参数同 pushState 方法
在 HTML5 History 出现之前,要记录页面状态和浏览器记录只能通过 Hash 和 iFrame 两种方式。可以借助第三方类库 History.js 进行兼容。


文章作者: Angus
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Angus !
  目录