HTML5学习笔记
HTML5文件的扩展名仍然是html或者htm,内容类型仍然是text/html,但是文档类型、编码格式等信息的声明有所简化:
1 2 3 4 5 6 7 8 9 10 |
<!DOCTYPE html> <!-- HTML DocType声明--> <html lang="en"> <head> <meta charset="UTF-8"><!-- 编码格式声明,推荐UTF-8 --> <title>HTML5 Study</title> </head> <body> <!-- body元素可以省略 --> </body> </html> |
HTML5在语法方面充分考虑了对HTML4的兼容性,以及便利性。
类型 | 说明 |
不允许结束标记 | 这类元素不得书写结束标记,仅支持 <br/> 或者 <br> 的形式。大部分不包含文本节点的元素在此类中,例如img、br、input、link、meta、param等 |
可选结束标记 | 结束标记可有可无,均合法。例如p、li、option、thead、tbody、tfoot、tr、td、th |
可以完全省略 | html、head、body、tbody、colgroup等元素可以完全省略不写 注意,这些元素不显式声明时,仍然存在于DOM模型中 |
disabled、checked、readonly等boolean值属性,当不提供值、值等于名或空格时,相当于设置属性为true;不提供属性名则相当于false。
当属性值不包含HTML特殊字符(< > = ' "等)时,可以省略包围属性值的引号。
HTML5新增了大量的JavaScript API,下表列举常用的部分:
API | 说明 |
CSS选择器 | 为Document、DocumentFragment、Element类型引入方法: querySelector(DOMString selectors) 和 querySelectorAll(DOMString selectors) 。分别返回第一个匹配选择器的元素,或者全部匹配元素的 NodeList 对象 |
离线应用 | 引入ApplicationCache类型,用于更新离线缓存,或者得到缓存更新的通知 |
多媒体 | HTMLAudioElement、HTMLVedioElement相关的方法和属性 |
Web SQL DB | 已经从标准中废弃,在浏览器上使用SQLLite数据库。Chrome等浏览器支持 |
Indexed DB | 用于存放简单的Key-Value形式的数据,通常应基于BTree实现 |
Web workers |
产生后台线程,执行JavaScript代码,与UI线程并行执行 |
Web storage | WindowLocalStorage、WindowSessionStorage,用于本地存储 |
Web sockets | 支持与服务器的双向通信 |
Server-sent Events | 用于服务器端单向推送 |
XMLHttpRequest2 | 支持跨域请求、上传进度事件等新功能 |
Geolocation | 用于获取客户端的地理位置信息 |
Canvas | 支持2D绘图 |
Form API | 扩展了新的表单API,例如表单校验 |
File API | 访问file类型input关联的文件 |
HTML5新增以下元素:
新增元素 | 说明 | ||
section | 表示页面中的一个内容区块,例如章节/页眉/页脚等 | ||
article | 表示于上下文不相关的独立内容,例如一篇文章 | ||
aside | 表示于article相关的辅助内容 | ||
header | 表示内容区块或者整个页面的标题 | ||
hgroup | 用于对内容区块或者整个页面的几个标题元素进行组合,通常用于对h1~h6分组 | ||
footer | 表示内容区块或者整个页眉的脚注 | ||
nav | 表示页面的导航链接部分 | ||
figure | 表示一段独立的流内容。通常是图片、统计图、代码示例,甚至音视频插件。 | ||
figurecaption | 为figure添加标题 | ||
video | 插入视频 | ||
audio | 插入音频 | ||
embed | 可用于插入多种多媒体格式 | ||
mark | 用于显示高亮元素 | ||
meter | 用于显示进度条 | ||
time | 用于显示时间 | ||
wbr | 软换行,当父元素空间不足时换行 | ||
canvas | 提供一张画布 | ||
details | 与summary联用,summary应该是其第一个子元素,点击后显示details的完整内容 | ||
datalist | 与input联用,提供可选值的下拉列表,并且支持自动完成。示例:
|
||
keygen | 用于生成密钥对,提交表单时,私钥存储在本地,公钥发送到服务器 | ||
output | 定义不同类型的输出,比如脚本的输出 | ||
source | 作为video/audio等的子元素,定义多个备选的媒体源 | ||
input | HTML5增加了多种input类型: email:必须输入电子邮件 url:必须输入URL number:必须输入数字 range:范围选择滑块 date、month、week、time、datetime、datetime-local:日期选取器 |
HTML5中删除的元素包括:
- 纯粹样式类元素:basefont、big、center、font、s、strike、tt、u,其功能使用CSS代替
- 不再使用frame元素,但是允许iframe
- 仅部分浏览器支持的元素:applet、bgsound、blink、marquee等
属性 | 说明 |
autofocus | 适用于text/select/textarea/button类型的表单元素,页面加载时自动获得焦点 |
placeholder | 适用于text/textarea,未输入时的提示文本 |
required | 适用于text/textarea,提交表单时执行校验,强制要求输入值 |
form | 声明表单元素属于哪个(或哪些)表单,进而允许将表单元素放置在页面的任何位置,而不限于表单内 |
autocomplete | 适用于input元素,是否使用输入字段的自动完成功能 可以设置为on/off或者"",最后一个值表示由浏览器决定是否启用自动完成 |
min | 适用于input元素,规定输入字段的最小值 |
max | 适用于input元素,规定输入字段的最打值 |
multiple | 适用于input元素,允许一次上传多个文件 |
list | 适用于text类型的input,指定此元素使用的datalist |
pattern | 适用于input元素,规定输入字段必须匹配的正则式 |
step | 适用于input元素,规定数字输入框的步进 |
disabled | 适用于fieldset元素,可以让其内部所有表单元素禁用 |
novalidate | 适用于input/button/form元素,用于取消提交时表单验证 |
form* | formaction、formenctype、formmethod、formnovalidate、formtarget,用于input/button元素,覆盖所属表单的对应属性 使用formaction,可以在点击不同按钮后,提交到不同的页面 |
spellcheck | 适用于text/textarea,是否允许拼写检查 |
validity | 适用于表单、表单元素,此属性的值类型是 ValidityState 对象,其包含多个属性,其中valid属性说明表单或者表单元素是否通过验证 |
accept | 用于限定file类型的input能接受的文件MIME类型, image/* 表示接受所有图片类型 |
属性 | 说明 |
media | 适用于a/area,链接目标文档为何种媒介/设备优化,必须和href属性联用 |
hreflang | 为area添加,以便和a/link元素一致 rel,规定当前文档与被链接文档之间的关系 hreflang,链接目标文档的语言 |
rel | |
target | 适用于base,保持和a元素一致 |
属性 | 说明 |
reversed | 适用于ol元素,倒序显示列表 |
start | 适用于ol元素,指定编号的起始值 |
charset | 适用于meta元素,指定文档的编码 |
scoped | 适用于style元素,使样式仅应用到DOM的某个子树 |
async | 适用于script元素,允许脚本异步执行 |
sandbox | 适用于iframe元素,提高安全性
|
seamless | |
srcdoc |
一些和样式有关的属性被废除,例如align、valign、bgcolor、background、border、cellpadding、cellspacing、width、height、nowrap等。
HTML5引入全局属性的概念,全局属性适用于任何元素。
属性 | 说明 |
contentEditable | 可以设置为true/false,添加此属性的任意(支持contentEditable的)元素,其内容可以编辑 |
designMode | 可以设置为on/off,如果设置为on,则整个页面下,所有支持Editable的元素均可编辑 |
hidden | 可以设置为true/false,可以设置任何元素为不可见状态 |
tabindex | 支持新的属性值-1,让元素无法通过Tab获得焦点 |
draggable | 可以设置为true/false,允许元素拖放。img/a元素默认支持备份 |
classList | 元素附加的CSS样式列表对象,支持add/remove/toggle等操作 |
HTML5引入的article、aside、section、header、footer等元素,让文档的结构更加清晰,容易阅读。需要注意这些元素和样式无关。
要在不完全支持HTML5的浏览器上使用这些元素,需要显式的声明这些元素如div一样,块式显示:
1 2 3 |
article, aside, dialog, figure, footer, header, legend, nav, section { display: block; } |
另外,IE8或者更低版本不支持直接通过上述样式表来定义未知元素的样式,需要先调用类似 document.createElement('article') 的脚本手工创建元素。
HTML5在以下方面增强了表单:
- 大量增加表单input元素的类型
- 表单和表单元素在DOM中可以不存在前后代关系
- 支持自动完成、占位符
- 支持多种日期/时间控件
- 支持完善的表单验证。属性required、min、max、pattern、setp以及input类型都为验证提供依据。表单提交时,会自动验证;手工调用表单或者表单元素的 checkValidity() 方法可以立即验证,此方法返回boolean值。验证完毕后,检查表单或者表单元素的 validity 属性可以获得详细的验证结果
HTML5提供了一套文件操作的API,使得从Web页面访问本地文件系统更加方便。
在HTML5中,一个file类型的input可以关联多个文件。input.files代表用户选择的文件对象的数组,此数组的每一个元素为File对象,代表单个文件:
1 2 3 4 5 6 7 8 9 10 11 12 |
<script type="text/javascript"> function showFileNames() { var file; var fileList = document.getElementById( 'file' ).files;//获取FileList对象 for ( var i = 0; i < fileList.length; i++ ) { file = fileList[ i ]; console.log( file.name ); } } </script> <input type="file" id="file" multiple="multiple"/> <input type="button" value="Upload" onclick="showFileNames()"> |
你可以访问File对象的以下属性:
属性 | 说明 |
name | 文件的名称 |
type | 文件的MIME类型,例如image/jpeg |
size | 文件的字节数 |
Firefox 3.6+和Chrome 6.0+实现了FileReader接口,使用它可以读取file类型input选取的文件的内容。要使用此接口,可以:
1 |
var fr = new FileReader(); |
此接口提供了以下几个方法:
方法 | 说明 |
readAsBinaryString(file) |
将文件读取为二进制编码,通常用于发送到服务器端 注意,此方法时异步的,不会立即返回读取结果,结果存放在 FileReader.result 字段中,下面的2个方法也是这样 |
readAsText(file, [encoding]) | 将文件读取为文本 |
readAsDataURL(file) | 将文件读取为Data URL字符串,可以直接在页面上使用(赋值给img.src属性),适用于小的图像 |
abort() | 终止读取操作 |
你必须注册回调函数还异步的处理读取结果,FileReader支持以下回调:
- onabort:数据读取操作被终止时调用
- onerror:数据读取出错时调用
- onloadstart:数据读取开始时调用
- onprogress:数据读取过程中调用
- onload:数据读取成功时调用
- onloadend:数据读取完成时调用,无论成功失败
尽管以前通过mousedown/mousemove/mouseup事件组合可以实现拖放操作,HTML5更进一步,直接支持原生的拖放事件。特别的,HTML5还支持与其它应用程序进行拖放交互,不限定在浏览器窗格内部。
- 检测浏览器是否支持原生HTML5拖放,可以使用Modernizr: if (Modernizr.draganddrop) {...}
- 将需要拖放的元素的draggable属性设置为true
- 编写拖放相关的事件监听器:
事件 Target 说明 dragstart 拖放源 按下鼠标,开始拖动操作的瞬间触发 drag 拖放源 拖动鼠标的过程中不断触发 dragenter 拖放时鼠标经过的元素 拖动鼠标进入某元素边界时触发 dragover 拖放时鼠标经过的元素 拖动鼠标在某元素内移动时不断触发 dragleave 拖放时鼠标经过的元素 拖动鼠标离开某元素边界时触发 drop 拖放目标 在拖放目标范围内,放开鼠标时触发 dragend 拖放源 拖放操作完毕后触发
下例展示了三个横向排列的可拖拽小方块,在不同的事件触发时,添加了样式:
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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
<style> /* 阻止选择draggable中的文本内容 */ [draggable] { -moz-user-select: none; -khtml-user-select: none; -webkit-user-select: none; user-select: none; /* 让老的webkit浏览器支持拖拽 */ -khtml-user-drag: element; -webkit-user-drag: element; } .column { height: 75px; width: 75px; float: left; border: 1px solid #669999; background-color: #cdd; margin-right: 10px; text-align: center; cursor: move; } .column header { color: #fff; background: #003333; } .column.gragover { border: 2px dotted #88AAAA; } </style> <div id="columns"> <!-- 只要设置此属性,就可以拖动,在Chrome下默认拖动效果是元素的半透明“重像副本”跟随鼠标移动 --> <div class="column" draggable="true"> <header>A</header> </div> <div class="column" draggable="true"> <header>B</header> </div> <div class="column" draggable="true"> <header>C</header> </div> </div> <script type="text/javascript"> var cols = document.querySelectorAll( '#columns .column' ); Array.prototype.forEach.call( cols, function ( col ) { col.addEventListener( 'dragstart', function ( e ) { //开始拖拽后,设置源的透明度 this.style.opacity = '0.3'; }, false ); col.addEventListener( 'dragenter', function ( e ) { //拖动进入本元素时,改变样式 this.classList.add( 'gragover' ); }, false ); col.addEventListener( 'dragleave', function ( e ) { //拖动离开本元素时,恢复样式 this.classList.remove( 'gragover' ); }, false ); //下面的事件会反复触发 col.addEventListener( 'dragover', function ( e ) { //如果拖动源是链接之类的元素,需要阻止默认行为,否则浏览器会导航到链接目标 e.preventDefault(); }, false ); col.addEventListener( 'drop', function ( e ) { e.stopPropagation(); //阻止浏览器的默认的重定向操作 }, false ); col.addEventListener( 'dragend', function ( e ) { //完成拖拽后,恢复源的透明度 this.style.opacity = '1'; //移除可能的高亮样式 [].forEach.call( cols, function ( col ) { col.classList.remove( 'gragover' ); } ); }, false ); } ); </script> |
使用 DataTransfer 对象,可以在拖拽的过程中完成数据的传输,在源和目标之间进行信息交换。你可以在dragstart时设置此对象,并在drop时读取并处理之。DataTransfer对象提供以下属性和方法:
属性/方法 | 说明 |
dropEffect | 控制用户在 dragenter 和 dragover 事件期间收到的视觉反馈。允许的值包括none、copy、link、move |
effectAllowed | 限制用户可以在源上执行的“拖拽操作类型”,以初始化dragenter和dragover事件中的dropEffect。允许的值包括none、copy、copyLink、copyMove、link、linkMove、move、all 、 uninitialized |
files | 从资源管理器拖拽文件到浏览器中时,存放拖入的文件列表对象 |
setDragImage(img element, x, y) | 设置拖拽时的图标,而不是使用默认的“重像副本” |
clearData(format) | 清除数据,format为MIME类型,如果传递此参数,则清除所有数据 |
setData(format,data) | 设置数据 |
getData(format) | 读取数据 |
1 2 3 4 5 6 7 8 9 |
function handleDrop( e ) { e.stopPropagation(); // 阻止浏览器默认的重定向行为 e.preventDefault(); var files = e.dataTransfer.files; for ( var i = 0, f; f = files[ i ]; i++ ) { //遍历文件,进行处理 } } |
HTML5引入的canvas元素,以及一套相关的API,大大增强了HTML绘制2D图形的能力。使用canvas绘制图形的一般性步骤如下:
- 取得canvas元素的引用
- 调用 canvas.getContext() 获得图形上下文(graphics context),此上下文封装了很多绘图功能
- 绘制图形,例如矩形、圆、路径,并设置图形样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!-- 注意,通过CSS设置画布大小,会导致其内部绘制变形 --> <canvas id="canvas" style="border: 1px dashed lightgray"></canvas> <script type="text/javascript"> /** * @type {HTMLCanvasElement} */ var canvas = document.getElementById( 'canvas' ); var ctx = canvas.getContext( '2d' ); ctx.clearRect( 50, 50, 50, 50 ); //清除矩形区域内的全部内容 ctx.fillStyle = '#88AAAA'; //填充样式 ctx.lineWidth = 2; //边框宽度 ctx.strokeStyle = "#558888"; //边框颜色 ctx.fillRect( 50, 50, 50, 50 ); //填充矩形 ctx.strokeRect( 50, 50, 50, 50 );//绘制矩形边框 </script> |
要绘制矩形之外的形状,需要使用到路径,路径可以勾勒出图形的轮廓。下面的例子绘制一个半圆:
1 2 3 4 5 6 7 |
ctx.beginPath();//开始创建新路径 //绘制圆弧,用此方法也可以绘制圆形。入参:x, y, radius, startAngle, endAngle, anticlockwise ctx.arc( 50, 50, 25, 0, 3 ); ctx.closePath();//关闭路径 //注意,此时尚未绘制任何图形,只是把路径给创建出来 ctx.fillStyle = 'rgba(128, 255, 255, 0.3)'; ctx.fill(); |
方法 | 说明 |
moveTo(x y) | 移动笔触到目标坐标 |
lineTo(x y) | 从当前点开始,向目标坐标绘制一直线 |
bezierCurveTo() | 绘制Bezier曲线 |
quadraticCurveTo() | 绘制二次曲线 |
createLinearGradient() | 绘制线性渐变 |
addColorStop() | 追加渐变颜色 |
createRadialGradient() | 绘制径向渐变(以圆心向外渐变) |
translate(x,y) | 坐标变换,平移 |
scale(x,y) | 坐标变换,放大 |
rotate(angle) | 坐标变换,旋转 |
transform() | 矩阵变换 |
drawImage() | 绘制图片 |
fillText() | 绘制文字 |
HTML5新增了 video 和 audio 两个元素,用于支持音视频,改变了以前依赖于第三方插件进行媒体播放的情况。下面是几个示例
1 2 3 4 5 6 7 8 9 10 |
<!DOCTYPE html> <!-- 音频 --> <audio src="song.mp3">Your browser doesn't support HTML5 audio element</audio> <!-- 视频 --> <video width="640" height="480" src="movie.mp4"></video> <!-- 可以指定多个媒体源,让浏览器选择自己支持的一种格式播放 --> <video> <source src="movie.ogv" type="video/ogg"/> <source src="movie.mov" type="video/quicktime" /> </video> |
各浏览器对音视频格式的支持不一。视频方面,VP8受到广泛支持;音频则一般需要提供OGG和MP3两种格式。
属性/方法/事件 | 说明 | ||
src | 媒体数据的URL | ||
autoplay | 是否在页眉加载后自动播放 | ||
preload | 是否进行预先加载以缓冲,支持none/metadata/auto metadata表示仅预加载媒体的元数据(媒体长度、第一帧、播放列表、持续时间等) |
||
poster | 仅video,当视频不可用时,显示一张图片在视频位置 | ||
loop | 是否循环播放 | ||
controls | 是否显示浏览器自带的控制工具条 | ||
width | 仅video,媒体的尺寸 | ||
height | |||
error |
在读取、播放过程中,如果出现错误,此字段不为null: 监听error事件,以使用该属性:
|
||
networkState |
在媒体下载过程中,读取网络状态: 监听progress事件,以使用该属性 |
||
currentSrc | 当前正在使用的媒体URL | ||
buffered | 返回一个实现TimeRanges接口的对象,检查已经缓冲的时间范围 | ||
readyState | 媒体在“当前位置”的就绪状态: HAVE_NOTHING:当前播放位置没有可播放数据 HAVE_METADATA:已获得元数据,但是当前位置无有效的媒体数据 HAVE_CURRENT_DATA:当前位置有数据可以播放,但是没有获得下一帧的数据,或者当前时最后一帧 HAVE_FUTURE_DATA:当前位置有数据可以播放,并且获得了下一帧数据 HAVE_ENOUGH_DATA:当前位置有数据可以播放,并且有足够数据供后续播放 |
||
seeking | 布尔值,浏览器是否正在请求某一特定位置的播放数据 | ||
seekable | 可Seek的TimeRanges对象 | ||
currentTime | 当前播放位置 | ||
startTime | 开始播放的位置,通常为0 | ||
duration | 媒体持续时间 | ||
played | 已经播放过的TimeRanges | ||
paused | 是否处于暂停状态 | ||
ended | 是否已经播放完毕 | ||
defaultPlaybackRate | 默认播放速率 | ||
playbackRate | 用于修改播放速率 | ||
volume | 音量,范围0-1 | ||
muted | 是否处于静音状态 | ||
play() | 播放 | ||
pause() | 暂停 | ||
load() | 重新载入媒体 | ||
canPlayType() | 是否支持指定的MIME类型,返回值:空串表示不支持;maybe表示可能支持; probably表示肯定支持 | ||
⚡loadstart | 开始加载媒体数据 | ||
⚡progress | 正在获取媒体数据 | ||
⚡suspend | 暂停获取媒体数据,但是下载未停止 | ||
⚡abort | 在下载完毕前中止获取媒体数据 | ||
⚡error | 下载或播放出现错误 | ||
⚡emptied | 网络变为未初始化状态,可能原因:下载过程中出现致命错误;load()被调用 | ||
⚡stalled | 尝试获取媒体数据失败 | ||
⚡play | 即将开始播放,调用play()后触发 | ||
⚡pause | 播放暂停,调用puase()后触发 | ||
⚡loadedmetadata | 已经获取到视频的元数据 | ||
⚡loadeddata | 已经加载当前播放位置的媒体数据,准备播放 | ||
⚡waiting | 因得不到下一帧数据而暂停 | ||
⚡playing | 正在播放 | ||
⚡canplay | 浏览器能播放媒体,但是以当前速率不能播放到结尾,期间需要缓冲 | ||
⚡canplaythrough | 浏览器能播放媒体到结尾 | ||
⚡seeking | 正在执行Seek操作 | ||
⚡seeked | Seek操作执行完毕 | ||
⚡timeupdate | 当前播放位置改变 | ||
⚡ended | 播放结束后停止播放 | ||
⚡ratechange | 播放速率改变 | ||
⚡durationchange | 时长改变 | ||
⚡volumechange | 音量改变或静音 |
传统的Cookie机制具有以下缺点:
- 尺寸限制:4KB
- 浪费贷款:随HTTP请求发送到服务器
- 复杂性:Cookie可能和特定的页面关联,比较难以操控
HTML5引入了两种新的客户端存储机制,用来代替Cookie,它们时Web Storage和本地数据库。
Web Storage分为两种:
- Session Storage:关闭浏览器后即消失。使用全局变量 sessionStorage 访问
- Local Storage:保存在磁盘中,即使关闭浏览器也不会消失 。使用全局变量 localStorage 访问
Web Storage的API非常简单,它们都使用基于Key-Value的存储方式,提供以下属性/方法:
属性/方法 | 说明 |
clear() | 清空存储 |
getItem(key) | 根据Key获取值 |
removeItem(key) | 根据Key移除值 |
setItem(key,value) | 根据Key设置值 |
length | 数据条目总数 |
key( index ) | 根据索引号得到第index-1条数据 |
此特性已经从HTML5标准中废弃,但是Chrome、Opera、Safari、Android Browser支持它。
HTML5内置了基于SQLLite的关系型数据库。 SQLLite是一种自包含、零配置的嵌入式数据库引擎。此本地数据库的用法和后端数据库很类似:
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 |
<script type="text/javascript"> /** * 打开或创建一个名为gmem的,预计大小为1MB的数据库 * @type {Database} */ var db = openDatabase( 'gmem', '1.0', 'Green memory database', 1 * 1024 * 1024 ); //开启一个读写事务 db.transaction( function ( tx ) { tx.executeSql( 'DROP TABLE IF EXISTS T_CORP' ); tx.executeSql( 'CREATE TABLE IF NOT EXISTS T_CORP (CORP_ID, NAME, REG_CAPI)' ); /** * SQL执行成功时的回调 * @param {SQLTransaction} tx * @param {SQLResultSet} results */ function dataHdl( tx, results ) { console.log( 'ID of inserted row: ' + results.insertId ); } /** * SQL执行失败时的回调 * @param {SQLTransaction} tx * @param {SQLError} err */ function errHdl( tx, err ) { console.log( err.message ); } var sql = 'INSERT INTO T_CORP VALUES (?, ?, ?) '; tx.executeSql( sql, [ 10000, "Sparknet. co.,ltd", 1500 ], dataHdl, errHdl ); tx.executeSql( sql, [ 10001, "Gmem studio", 25 ], dataHdl, errHdl ); } ); //开启一个读事务 db.readTransaction( function ( tx ) { tx.executeSql( 'SELECT * FROM T_CORP', [], function ( tx, results ) { Array.prototype.forEach.call( results.rows, function ( row ) { console.log( row.NAME ); } ) } ); } ); </script> |
传统Web应用的致命缺点是,与Internet断开连接时,无法使用。HTML5引入一个本地缓存机制,允许在离线状态下访问Web页面,当无法连接Internet时,浏览器自动访问本地缓存中的HTML、CSS、Javascript等文件。
- 本地缓存只处理你指定的网页,对哪些资源进行缓存。浏览器缓存无法进行这些细致的控制
- 浏览器缓存仍然需要网络连接才能生效
manifest文件负责声明哪些资源需要被缓存,以及资源的路径。你可以为每个页面指定manifest文件,或者为整个应用声明一个manifest文件。manifest文件的格式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
CACHE MANIFEST #必须以上一行开头 #有三种类别的声明,每个类别都可以重复编写: CACHE #声明需要缓存到本地的资源文件,为一个页面指定manifest时,页面本身自动在此类别下,不需要声明 NETWORK #声明不得进行缓存的资源文件 #通配符表示没有显式声明的文件,默认都不缓存 * FALLBACK #每行指定两个文件,第一个为能够在线访问时使用的文件,第二个为离线时使用的文件 online.js offline.js |
HTML5规定manifest的MIME类型为text/cache-manifest,你的Web服务器必须支持此MEME类型,以Apache2为例:
1 |
text/cache-manifest manifest |
编写好manifest文件后,需要到HTML文件中引用之:
1 |
<html manifest="global.manifest"></html> |
此对象表示本地缓存,当本地缓存更新后,可以通过此对象获得通知,你也可以通过此对象手工更新缓存:
1 2 3 4 |
applicationCache.onUpdateReady = function () { console.log( 'Local cache updated' ); } applicationCache.swapCache();//手工更新缓存,页面刷新后生效 |
HTML5支持在不同网页之间进行消息收发,只需要获得目标窗口的引用就可以发送消息,可以跨域通信:
1 2 3 4 5 |
window.addEventListener( 'message', function () { } ); var targetOrigin = "*"; //一般使用目标窗口的URL,例如http://localhost:8080/,*表示通配符 otherWindow.postMessage( message, targetOrigin ); |
使用HTML5的Web Sockets API,可以在客户端和服务器之间建立一个非HTTP的双向通信连接。使用WebSockets可以轻易的实现数据推送,而避免客户端轮询。
进行WebSockets通信时,必须使用ws或者wss(加密通信)的URL前缀:
1 |
var socket = new WebSocket("ws://gmem.cc:8808/socket"); |
使用WebSockets收发数据非常简单:
1 2 3 4 5 6 7 8 9 |
//向服务器发送数据 socket.send('文本数据'); //通过回调函数来接收服务器发送来的数据 socket.onmessage = function(event){ var data = event.data; } //监听套接字开关事件 socket.onopen = function(event){} socket.onclose = function(event){} |
不再需要使用时,可以关闭WebSocket:
1 |
socket.close() |
另外,你可以读取 readyState 属性,获取WebSocket的状态,可能的值包括:CONNECTING(正在连接);OPEN(已经连接);CLOSING(正在关闭);CLOSED(已经关闭)。
- 客户端和服务器仅仅建立一个TCP连接
- 支持从服务器推送数据到客户端
即第二级XMLHttpRequest,HTML5增强了其功能,并且支持CORS。
XHR2支持设置响应类型,你可以将 xhr.responseType 设置为text、arraybuffer、blob、document等值,responseType的设置的值不同,则response中数据的组织方式也不同。
下面的例子中,我们以二进制方式读取服务器响应,并作为图片插入到DOM:
1 2 3 4 5 6 7 8 9 10 |
xhr.responseType = 'blob'; var bb = new BlobBuilder(); bb.append( xhr.response ); var blob = bb.getBlob( 'image/png' ); var img = document.createElement( 'img' ); img.onload = function ( e ) { window.URL.revokeObjectURL( img.src ); // 清理 }; img.src = window.URL.createObjectURL( blob ); document.body.appendChild( img ); |
类似的,当设置响应类型为arraybuffer时,可以:
1 2 |
var uInt8Array = new Uint8Array( this.response ); var byte3 = uInt8Array[ 4 ]; |
以前XHR限制仅能发送DOMString或者Document(XML)类型的数据,XHR2修改过的 send() 方法支持多种类型的数据,包括DOMString、Document、FormData、Blob、File、ArrayBuffer。下面的代码示例了如何发送文本数据:
1 2 3 4 5 6 7 8 9 |
var xhr = new XMLHttpRequest(); xhr.open( 'POST', '/server', true ); xhr.responseType = 'text'; xhr.onload = function ( e ) { if ( this.status == 200 ) { console.log( this.response ); } }; xhr.send( 'text' ); |
下面的代码示例了如何提交表单:
1 2 3 4 5 6 7 8 9 |
var form = document.getElementById( 'formId' ); //获取表单数据 var formData = new FormData( form ); formData.append( 'secret_token', '1234567890' ); // 附加额外数据 var xhr = new XMLHttpRequest(); xhr.open( 'POST', form.action, true ); xhr.onload = function ( e ) { }; xhr.send( formData ); |
下面的数据示例了如何上传BLOB:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var xhr = new XMLHttpRequest(); xhr.open( 'POST', '/server', true ); xhr.onload = function ( e ) { }; // 监听上传进度 var progressBar = document.querySelector( 'progress' ); xhr.upload.onprogress = function ( e ) { if ( e.lengthComputable ) { var pcnt = (e.loaded / e.total) * 100; //进度 } }; var bb = new BlobBuilder(); bb.append( 'hello world' ); bb.getBlob( 'text/plain' xhr.send( bb ); </script> |
上传文件时处理方式类似,只需要通过File API读取文件的内容即可。
在以前,Web应用都是“单线程”的,通过Web Workers,HTML5引入了类似后端开发的多线程功能。 使用Web Workers,你可以把一部分工作安排在后端线程中执行,而不必影响UI渲染线程。
要创建后台线程,你可以:
1 2 |
//入参为新线程需要执行的脚本 var worker = new Worker('worker.js'); |
后台线程不能访问页面、窗口等对象,需要注意这个限制。如果要同后台线程交互,可以通过消息机制:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* 父线程 */ //发送消息给子线程 worker.postMessage('Hello'); //监听消息 worker.onmessage = function (event) { console.log(event.data); } /* 子线程的脚本文件中 */ //监听消息 self.onmessage = function (event) { //向父线程发送消息 self.postMessage('World'); } |
注:上述代码中的onmessage属性可以用 addEventListener('message',function(e){}) 代替。
变量/函数/对象 | 说明 |
self | 表示本线程的作用域对象 |
postMessage(message) | 向创建线程的源窗口发送消息 |
onmessage | 获得用于接收事件的回调函数 |
importScripts(urls) | 导入其它脚本文件,支持多个脚本 |
navigator | 类似于window.navigator |
sessionStorage/localStorage | 本地存储 |
XMLHttpRequest | 支持发送XHR请求 |
Web Workers | 支持嵌套创建的子线程 |
setTimeout()/setInterval() | 支持定时器 |
terminate() | 当一个线程被创建后,它会持续的监听外部消息,即使脚本已经完毕 必须显式调用此方法,来关闭线程,释放资源 |
eval()/isNaN()/escape() ... | 支持任何JavaScript核心函数 |
WebSockets | 支持Web Sockets |
HTML5包含了一套Geolocation API,可以用来获取客户端的地理位置信息,这要求浏览器支持、并且设备具有定位功能。通过 window.navigator.geolocation 可以访问这些API,主要包括下面三个方法:
void getCurrentPosition (onSuccess, onError, options) |
立即获取当前位置信息,三个入参: onSuccess,成功获取位置时执行的回调,格式:
onError,获取位置失败时执行的回调,可选 |
||
int watchCurrentPosition (onSuccess, onError, options) |
持续监控当前位置信息,定期回调,返回一个watchId | ||
void clearWatch(watchId) | 取消既有的持续监控 |
成功回调函数的入参是一个position对象,其包含了多种位置信息参量:
latitude | 当前维度 |
longitude | 当前经度 |
altitude | 当前海拔高度 |
accuracy | 经纬度的精度(单位m) |
altitudeAccuracy | 海拔的精度(单位m) |
heading | 设备前进方向,正北顺时针旋转的角度 |
speed | 设备前进速度(单位m/s) |
timestamp | 获得地理位置信息的时间戳 |
所谓视口(Viewport)就是指浏览器/webview上能够显示网页内容的那部分区域。
视口的的尺寸不一定等于浏览器可视区域的尺寸。因为移动设备的(CSS逻辑)分辨率比桌面设备低,为了能够正常显示为桌面设备制作的传统网站,移动设备浏览器通常把自己的视口宽度设置为980px或者1024px——比浏览器可视区域宽度大,这就导致会出现横向滚动条。
移动设备中,CSS的一个像素,也不一定代表一个物理像素。以Iphone4为例,一个CSS像素对应了4个物理像素。 windiw.devicePixelRatio 表示单位长度内,物理像素数量 / CSS逻辑像素数量的比值,Iphone4中该比值为2。
可以使用meta标签对视口进行控制:
1 2 3 4 5 6 7 |
<!-- width 视口的宽度,可以设置为width-device表示适应设备的宽度 initial-scale 页面的初始缩放比率 maximum-scale 页面的最大缩放比率 user-scalable 是否允许用户来缩放 --> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> |
Leave a Reply